Architecture-components-samples: findNavController().navigate(R.id.action) always destroy my current fragment

Created on 27 Oct 2019  路  10Comments  路  Source: android/architecture-components-samples

Well I have some case and need to keep my current fragment even I open some new fragment, but when I put findNavController().navigate(R.id.someaction) in my click listener, its always destroy my current fragment, I already search on StackOverflow but im not found any solution for this :(
Thank you

Most helpful comment

Not even a convincing solution I got for the issue. Whenever a component released for android by google is not up to the mark always. Those components or feature covers only half of the test cases.
I don't think it is necessary to destroy the current fragment to navigate to another with navController. I think this is a valid issue to be sorted out.

All 10 comments

Why you care about current Fragment destruction?
You should not have data in your Fragment but in a ViewModel associated with it instead.
If your Fragment gets destroyed due to any configuration change you will lose your state data anyways.
The stateless your Fragment is, the better. Fragments should only care about its View logic and the Lifecycle events. Other logic don't belong there.

Because I have recyclerview of product at fragment A and when I click findNavController().navigate(R.id.actionFragAtoFragB) to open detail of product, the problem is when I'm on fragment B and then back to fragment A the scroll position of recyclerview got reset because the Fragment A has been destroyed when I move to Fragment B

My app https://github.com/hoc081098/ComicApp work well with Navkgation Component

@kadaluarsa I see your point. There is definitely some use cases where not destroying the fragment data will improve the performance. Your case is one of them.
I think you can save your current recyclerView position in your ViewModel and when your fragment is recreated back, then set that position again. Of-course is not perfect since the user may experience a little jump.
There is an issue open for this already. If you watch 2019 Android Summit recently. Ian Lakes gave a talk about the future of Fragments. They are planning to save the state of the Fragments in back stack.

You telling me the fragment is getting destroyed or is the fragment's view getting destroyed?
Every time you navigate back to a fragment it's view gets recreated but not the fragment instance.
verify if on destroy is being called and if you are not instantiating the adapter multiple time because you instantiate it in onCreateView or on one of the subsequent lifecycle callbacks.

@kadaluarsa If you set an id to the recycler view and parent views the scroll state should be automatically re-created even if the view is getting destroyed.

The ids is the only way the framework can save the view state :)

Fragments already save the view state of Fragments on the back stack. If you're handling configuration changes and process death (i.e., testing with 'Don't keep activities') correctly, you'll also handle being on the back stack without issues.

Not even a convincing solution I got for the issue. Whenever a component released for android by google is not up to the mark always. Those components or feature covers only half of the test cases.
I don't think it is necessary to destroy the current fragment to navigate to another with navController. I think this is a valid issue to be sorted out.

Not even a convincing solution I got for the issue. Whenever a component released for android by google is not up to the mark always. Those components or feature covers only half of the test cases.
I don't think it is necessary to destroy the current fragment to navigate to another with navController. I think this is a valid issue to be sorted out.

True.
And combined with the live data observers, which I don't want it to be called many times in onCreateView, even make the logic more of a mess.

I have same issue with you @kadaluarsa , to fix that you must initialize adapter outside fragment lifecycle, for example

class MyFragment : Fragment() {

private val myViewModel by viewModel<MyViewModel>()
private val myAdapter = MyAdapter()

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    Log.d("checkListData", myAdapter.currentList.toString())
    myViewModel.someListData.observe(viewLifecycleOwner){ listData ->
        myAdapter.submitList(listData)
    }
}

}

Was this page helpful?
0 / 5 - 0 ratings