android / architecture-components-samples

Samples for Android Architecture Components.
https://d.android.com/arch
Apache License 2.0
23.4k stars 8.29k forks source link

Navigation, Saving fragment state #530

Closed ibrahimAlii closed 5 years ago

ibrahimAlii commented 5 years ago

Hi, I'm was trying to save fragment state, Is there a suggested way to use while using Navigation component?

It's like open new fragment without lose the previous fragment states.

ghost commented 5 years ago

Do you really need to save fragment state while using Navigation?

Slim1991 commented 5 years ago

Yes, I do. It's like using FragmentTransaction.show()/hide()

lymons commented 5 years ago

Yes, I do. It's like using FragmentTransaction.show()/hide()

You are right. Using FragmentTransaction.add()/show()/hide() by override the method navigate() of FragmentNavigator

Slim1991 commented 5 years ago

You are right. Using FragmentTransaction.add()/show()/hide() by override the method navigate() of FragmentNavigator

Can u tell more detail about it? I can imagine about it, but for working, not yet :D

ghost commented 5 years ago

Stop imagining things! haha

lymons commented 5 years ago

You are right. Using FragmentTransaction.add()/show()/hide() by override the method navigate() of FragmentNavigator

Can u tell more detail about it? I can imagine about it, but for working, not yet :D

you can see this repo. https://github.com/STAR-ZERO/navigation-keep-fragment-sample

Slim1991 commented 5 years ago

You are right. Using FragmentTransaction.add()/show()/hide() by override the method navigate() of FragmentNavigator

Can u tell more detail about it? I can imagine about it, but for working, not yet :D

you can see this repo. https://github.com/STAR-ZERO/navigation-keep-fragment-sample

In the case of that repo, fragments are not destroyed when navigating but they are recreate view all the time by onCreateView(). I want when I pop fragments from backstack, they are not recreate view like I do with the FragmentTransaction

lymons commented 5 years ago

You are right. Using FragmentTransaction.add()/show()/hide() by override the method navigate() of FragmentNavigator

Can u tell more detail about it? I can imagine about it, but for working, not yet :D

you can see this repo. https://github.com/STAR-ZERO/navigation-keep-fragment-sample

In the case of that repo, fragments are not destroyed when navigating but they are recreate view all the time by onCreateView(). I want when I pop fragments from backstack, they are not recreate view like I do with the FragmentTransaction

The reason fragments are recreated is using attach/detach in navigate method of KeepStateNavigator class, so you should know that the correct is use show/hide instead of attach/detach.

Slim1991 commented 5 years ago

You are right. Using FragmentTransaction.add()/show()/hide() by override the method navigate() of FragmentNavigator

Can u tell more detail about it? I can imagine about it, but for working, not yet :D

you can see this repo. https://github.com/STAR-ZERO/navigation-keep-fragment-sample

In the case of that repo, fragments are not destroyed when navigating but they are recreate view all the time by onCreateView(). I want when I pop fragments from backstack, they are not recreate view like I do with the FragmentTransaction

The reason fragments are recreated is using attach/detach in navigate method of KeepStateNavigator class, so you should know that the correct is use show/hide instead of attach/detach.

yeah, yeah, I know. haha. But the point is I haven't succeed yet when I replace attach/detach by show/hide in the KeepStateNavigator class :D

dishantkawatra commented 5 years ago

Any One solved the issue please let me know

ghost commented 5 years ago

Did you guys manage to solve this?

linhphan0108 commented 5 years ago

keep waiting lol

donniesky commented 5 years ago

keep waiting too !!

ianhanniballake commented 5 years ago

Please file feature requests on the Navigation library on the issue tracker with your use case.

Osaigbovo commented 5 years ago

Still waiting...

ibrahimAlii commented 5 years ago

Still waiting...

https://issuetracker.google.com/issues/127932815

liveHarshit commented 5 years ago

You can use: https://github.com/googlesamples/android-architecture-components/tree/master/NavigationAdvancedSample

JonathanImperato commented 5 years ago

Following...+1

Osaigbovo commented 5 years ago

The fix is buggy and not good enough. The legion is waiting Ian...

wahdatjan commented 5 years ago

I use bottom navigation which has three tabs A B and C when i go from tab A to Tab B then i revisited to tab A it recreates the tab A i want to save fragment state dont want to recreate the fragment A.

SogoGolf commented 5 years ago

same. this is crazy, cmon google! way way easier on iOS.

zedlabs commented 5 years ago

the only probable solution right now is to not use Navigation unfortunately

JonathanImperato commented 5 years ago

Currently the only working solution I found is to store the different fragment states in a shared viewmodel. Fortunately the navigation components helps us in this way with a custom Library built method called navGraphViewModel.

Robotecom commented 5 years ago

could you share a piece of code of your working solution @JonathanImperato ?

JonathanImperato commented 5 years ago

could you share a piece of code of your working solution @JonathanImperato ?

Look at this. Just use it like a normal ViewModel that is global to every fragment available in the navigation graph.

StevenWT commented 5 years ago

I want to save fragments state. Fragments according to official used the replace() method that doesn't save fragment state, but we expect to use the add()/hide() methods shows fragments to save fragment state. My solution is to not use the official implementation implementation "androidx.navigation:navigation-fragment:$nav_version", directly put the library's code in your project, and then modify the replace() method to hide()/add() method.

public NavDestination navigate(@NonNull Destination destination, @Nullable Bundle args,
            @Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras) {

//      ft.replace(mContainerId, frag);

//      change to  

        if(mFragmentManager.getFragments().size()>0){
            ft.hide(mFragmentManager.getFragments().get(mFragmentManager.getFragments().size()-1));
            ft.add(mContainerId, frag);
        }else {
            ft.replace(mContainerId, frag);
        }

}

I have a demo you can run. fragment-demo

JonathanImperato commented 5 years ago

Have a look also at this: https://developer.android.com/guide/navigation/navigation-programmatic#share_ui-related_data_between_destinations_with_viewmodel

iRYO400 commented 5 years ago
/**
 * Manages the various graphs needed for a [BottomNavigationView].
 *
 * This sample is a workaround until the Navigation Component supports multiple back stacks.
 */

https://github.com/googlesamples/android-architecture-components/blob/master/NavigationAdvancedSample/app/src/main/java/com/example/android/navigationadvancedsample/NavigationExtensions.kt

Sounds not cool :/

iRYO400 commented 5 years ago

What about NavigationView, nothing is here

ChristopherME commented 4 years ago

Did Google solve the retain instance problem?

vadimleonov commented 4 years ago

We are still waiting! :D

simplepeng commented 4 years ago

We are still waiting! :D

Slim1991 commented 4 years ago

I want to save fragments state. Fragments according to official used the replace() method that doesn't save fragment state, but we expect to use the add()/hide() methods shows fragments to save fragment state. My solution is to not use the official implementation implementation "androidx.navigation:navigation-fragment:$nav_version", directly put the library's code in your project, and then modify the replace() method to hide()/add() method.

  • androidx.navigation.fragment.FragmentNavigator.java
public NavDestination navigate(@NonNull Destination destination, @Nullable Bundle args,
            @Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras) {

//      ft.replace(mContainerId, frag);

//      change to  

        if(mFragmentManager.getFragments().size()>0){
            ft.hide(mFragmentManager.getFragments().get(mFragmentManager.getFragments().size()-1));
            ft.add(mContainerId, frag);
        }else {
            ft.replace(mContainerId, frag);
        }

}

I have a demo you can run. fragment-demo

Sound good, we can solve the problem this way. But copy all related source codes then modify one line of codes is not a good behavior. I'm also trying to extends FragmentNavigator but can not change super()'s logic. Google should open it for us can customize

luongfrv2522 commented 4 years ago

We are still waiting! :|

PascalTang commented 4 years ago

We are still waiting! :|

kx30 commented 4 years ago

We are still waiting! :|

MustafaFidan1991 commented 4 years ago

i guess we are still waiting :)

KKChong commented 4 years ago

We are still waiting! :|

cauchywei commented 4 years ago

We are still waiting! :|

dziry commented 4 years ago

We are still waiting! :|

farhanahmed95 commented 4 years ago

I found a work around, the key is to create your own NavHostFragment and custom fragment navigator and set it inside your custom NavHostFragment.

i used code from from nav component library and made edit for adding and hiding fragments.

https://gist.github.com/farhanahmed95/a33aaabdb4fb602d515005c34e864ffe

douo commented 4 years ago

Reuse the View can fix the problem in most cases:

abstract class DataBindingFragment<T : ViewDataBinding> : Fragment() {
    lateinit var binding: T
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        if (!::binding.isInitialized) {
            binding = onCreateDataBinding(
                inflater,
                container,
                savedInstanceState
            )
        }
        return binding.root
    }

    abstract fun onCreateDataBinding(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): T
}
IslamKhSh commented 4 years ago

Any solution or optimized work around?? We are still waiting !!

10zgurr commented 4 years ago

come on!!! I don't want to send the same request every time the user tapped the bottom navigation bar!!! solve it please! every time when we tap the bottom navigation view fragment item it creates the whole fragment again! what is the point??? you make us regret to use new components!!!

10zgurr commented 4 years ago

I update the navigation extensions class and the state problem has fixed:

https://gist.github.com/theozgurr/506895a4f0f820a6c60e97eb6026198b

amirreza-sobhdel commented 4 years ago

anybody out there?! google!

tomtaila commented 4 years ago

Why is this closed it's not fixed ffs? What a joke

0xMatthewGroves commented 4 years ago

Yeah... the navigation component has been my least favorite androidx library. I am guessing they are working on a complete revamp judging by the silence so far.

Should have never been moved out of beta given the limitations (no fragment reuse being among them).

IuraGaitur commented 4 years ago

I update the navigation extensions class and the state problem has fixed:

https://gist.github.com/theozgurr/506895a4f0f820a6c60e97eb6026198b

It is not working with <dialog tags, it is crashing :(

10zgurr commented 4 years ago

I update the navigation extensions class and the state problem has fixed: https://gist.github.com/theozgurr/506895a4f0f820a6c60e97eb6026198b

It is not working with <dialog tags, it is crashing :(

did you mean dialog fragments?