Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigation Component .popBackStack() with arguments

Tags:

I have Two fragment. SecondFragment and ThirdFragment. Actually I use the Navigation Component for passing value between fragments. Like this:

SecondFragment:

val action = SecondFragmentDirections.action_secondFragment_to_thirdFragment().setValue(1)

Navigation.findNavController(it).navigate(action)

Here is how I read the value from the ThirdFragment:

 arguments?.let {
           val args = ThirdFragmentArgs.fromBundle(it)
           thirdTextView.text = args.value.toString()
       }

It's work fine. Now my stack is look like this:

ThirdFragment

SecondFragment 

There is any option for pass value from the opened ThirdFragment to the previous SecondFragment with the new Navigation Component? (When ThirdFragment is finishing)

I know about onActivityResult, but If Nav.Component serve better solution than I want use that.

Thank you!

like image 235
vihkat Avatar asked Jul 13 '18 13:07

vihkat


People also ask

What is popBackStack inclusive?

popBackStack(backStackId, INCLUSIVE) will pop all the fragments (states) back to backStackId, so once you pop the lowest i that you're going to pop, all the higher ones should get popped at the same time.

How do you navigate between fragments in Kotlin?

First, you create a Navigation resource file (usually referred to as Nav Graph), where you add the fragments you wish to connect. Make sure to give an ID to each fragment (that's what you'll use to navigate between them later).


2 Answers

It's a bit late for this answer but someone may find it useful. In the updated versions of the navigation component library it is now possible to pass data while navigating back.

Suppose the stack is like this

FragmentA --> FragmentB.

We are currently now in FragmentB and we want to pass data when we go back to FragmentA.

Inside FragmentAwe can create an observer with a key:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val navController = findNavController()
// Instead of String any types of data can be used
navController.currentBackStackEntry?.savedStateHandle?.getLiveData<String>("key")
    ?.observe(viewLifecycleOwner) { 

    }
}

Then inside FragmentB if we change its value by accessing previous back stack entry it will be propagated to FragmentA and observer will be notified.

val navController = findNavController()
navController.previousBackStackEntry?.savedStateHandle?.set("key", "value that needs to be passed")
navController.popBackStack()
like image 125
Alif Hasnain Avatar answered Oct 18 '22 12:10

Alif Hasnain


Just came across setFragmentResult(), pretty easy to use. The docs on this are here.

If you are navigating: Fragment A -> Fragment B -> Fragment A Add this to fragment A:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setFragmentResultListener("requestKey") { requestKey, bundle ->
        shouldUpdate = bundle.getBoolean("bundleKey")
    }
}

Then in fragment B add this line of code:

setFragmentResult("requestKey", bundleOf("bundleKey" to "value to pass back"))
// navigate back toFragment A

When you navigate back to fragment A the listener will trigger and you'll be able to get the data in the bundle out.

like image 41
Al Rosenthal Avatar answered Oct 18 '22 14:10

Al Rosenthal