3

I am using bottom navigation.

In the switched screen, there is also a function to open a dialog fragment.

I also used navigation for this.

This is because, as soon as this dialog is finished, data must be delivered to the screen that opened the dialog.

I used safe args for this.

But I got the same error as the title.

i know where the error is, but i don't know exactly why it occurred.

According to a search on Stack Overflow, there are people who have had the same problem as me, but it doesn't seem to be an exact solution because the cases are different.

nav_graph

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/calendar">
    <fragment
        android:id="@+id/calendar"
        android:name="com.example.writeweight.fragment.CalendarFragment"
        android:label="fragment_calendar"
        tools:layout="@layout/fragment_calendar" >
    </fragment>
    <fragment
        android:id="@+id/list"
        android:name="com.example.writeweight.fragment.WorkoutListFragment"
        android:label="fragment_workout_list"
        tools:layout="@layout/fragment_workout_list" />
    <fragment
        android:id="@+id/write"
        android:name="com.example.writeweight.fragment.WritingRoutineFragment"
        android:label="WritingRoutineFragment"
        tools:layout="@layout/fragment_writing_routine">
        <action
            android:id="@+id/action_write_to_bodyPartDialog"
            app:destination="@id/bodyPartDialog" />
        <argument
            android:name="title"
            app:argType="string"
            android:defaultValue="Write" />
    </fragment>
    <dialog
        android:id="@+id/bodyPartDialog"
        android:name="com.example.writeweight.fragment.BodyPartDialogFragment"
        android:label="BodyPartDialogFragment"
        tools:layout="@layout/fragment_body_part_dialog">
        <action
            android:id="@+id/action_bodyPartDialog_to_write"
            app:destination="@id/write">
        </action>
    </dialog>
</navigation>

MainActivity

class MainActivity : AppCompatActivity() {
    private lateinit var bottomNav: BottomNavigationView
    private lateinit var navController: NavController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        bottomNav = findViewById(R.id.bottom_nav)
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_container) as NavHostFragment
        navController = navHostFragment.navController
        bottomNav.setupWithNavController(navController)
    }
}

DialogFragment

class BodyPartDialogFragment : DialogFragment() {
    private lateinit var ll: LinearLayout
    private lateinit var startBtn: Button
    private lateinit var title: String

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view: View = inflater.inflate(R.layout.fragment_body_part_dialog, container, false)

        initView(view)
        setLayout()

        startBtn?.setOnClickListener { v ->
            title = BodyPartCustomView.getTitle()
            val action = BodyPartDialogFragmentDirections.actionBodyPartDialogToWrite(title)
            findNavController()?.navigate(action) // Possibly the location of the error.
            dismiss()
            
        }
        return view
    }

    private fun initView(view: View) {
        ll = view.findViewById(R.id.ll_body_part)
        startBtn = view.findViewById(R.id.start)
    }

    private fun setLayout() {
        ll?.apply { clipToOutline = true }
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog:Dialog = super.onCreateDialog(savedInstanceState)
        dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        dialog.setCanceledOnTouchOutside(false)
        return dialog
    }

    override fun onDismiss(dialog: DialogInterface) {
        Toast.makeText(context, "CHECK", Toast.LENGTH_SHORT).show()
    }
}
ybybyb
  • 1,385
  • 1
  • 12
  • 33
  • 1
    There's [very specific guidance for returning a result from a DialogFragment](https://developer.android.com/guide/navigation/navigation-programmatic#additional_considerationshttps://developer.android.com/guide/navigation/navigation-programmatic#additional_considerations). Is there a reason you aren't following that guidance? – ianhanniballake Jun 14 '21 at 21:58
  • 1
    Looks like you have several `NavController`s and method `findNavController` return wrong NavController for your case. – Artem Viter Jun 14 '21 at 22:15
  • @ianhanniballake I just watched [this](https://developer.android.com/guide/navigation/navigation-getting-started.) and followed it. I thought I could just refer to this. Anyway, I'll try by referring to your link. – ybybyb Jun 15 '21 at 17:29
  • @ianhanniballake Ummm... not according to your link... but using `navigate()` in the `fragment` that opens the `dialog` solved it. I didn't post the fragment's code in the main body, but I actually opened the dialog using the `constructor` and `show()`, not `navigate()`. So I guess that was the problem. By the way, the link you gave also seems to be about dialog, but I don't know what the documentation is trying to say. – ybybyb Jun 15 '21 at 18:51

3 Answers3

5

It can be resolved by checking the current destination first before navigating

For example

Fragments A, B, and C

navigating from A to B while clicking on a button in fragment A that navigates to C might lead to crashes in some cases

for that you should check the current destination first as follows:

if(findNavController().currentDestination?.id==R.id.AFragment)
   findNavController().navigate(
   AFragmentDirections.actionAFragmentToCFragment()
 )
Astro
  • 376
  • 5
  • 11
  • This is what I'm going with but it seems there should be a better way where I don't have to make extra actions when I only plan on navigating from the DialogFragment. – DarkOhms Sep 22 '22 at 21:40
0

maybe you can just make sure id in fragment navigation is same with id in menu button because i already experienced it

Yosua Haloho
  • 11
  • 1
  • 2
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 02 '23 at 10:08
0

This is how I fixed, I cange the FragmentDirections action for the destination Id ej : navController.navigate(R.id.MainNavigation) .

In my case, I have two navigations graph and I was trying to navigate between graph. I hope this would help someone