2

Im using the android navigation component and despite some early teething issues it is now working well.

I'm keeping to the one activity many fragments design principle and I'm using shared view models to communicate between fragments.

I now have a scenario in my application where the user creates something, saves it, and is returned to the main list fragment (think something like adding a new contact except it involves a lot more than just typing in some boxes)

When the user saves the information I need to clear the data from my view models (this is due to security concerns and not performance) as they are shared view models and so are tied to the activity lifecycle and not the fragment, so they won't clear themselves, I can achieve this in a normal flow just setting data to null and calling navcontroller.popBackStack() but if the user presses back themselves I have no way of knowing and thus cannot clear these view models, any ideas?

martinseal1987
  • 1,862
  • 8
  • 44
  • 77
  • 1
    Maybe you can implement a listener interface (say OnBackPressedListener) and use it in your respective fragments to take action upon back button presses (or up navigation). The interface will be your bridge between your fragments and the activity. – Onur D. Dec 12 '18 at 20:59
  • 1
    Here I found an example of this approach https://stackoverflow.com/a/52997438/8354184 – Onur D. Dec 12 '18 at 21:02
  • 1
    @OnurD. i dont like it lol, but it definitely answers the question so thank you, if you add this as an answer ill accept it – martinseal1987 Dec 13 '18 at 08:13
  • Just did. Thank you! – Onur D. Dec 13 '18 at 09:44

2 Answers2

2

You can implement a listener interface (say OnBackPressedListener) and use it in your respective fragments to take action upon back button presses (or up navigation). The interface will be your bridge between your fragments and the activity.

Onur D.
  • 515
  • 3
  • 11
  • the reason i dont like this is that to do it i need to know which fragment is shown and if it implements the interface, this can be done by getting the navHost but i have many navHosts so will probably implement a view model that stores the current nav host which sucks in my opinion – martinseal1987 Dec 13 '18 at 10:06
  • 1
    @martinseal1987 if you still have this problem, with the latest release now we have an OnNavigateUpListener. https://developer.android.com/reference/androidx/navigation/ui/AppBarConfiguration.OnNavigateUpListener – Onur D. Jan 03 '19 at 20:29
  • wow this will be a big help thanks for pointing this out, Id actually just tied a view model to the activity just to accomplish this yesterday – martinseal1987 Jan 04 '19 at 09:36
  • 1
    I happened to have the same problem in one of my projects and I played with this listener interface yesterday. I found out that this is actually intended to be used for another issue (nested navhosts). So I decided to go with a custom interface myself :) But feel free to try it, hope you can make it work for your case. – Onur D. Jan 04 '19 at 10:03
  • my scenario was nested nav hosts – martinseal1987 Jan 04 '19 at 10:04
1

The correct way to do this I don't think was available at the time but you should scope your view models to your navigation graphs, this way the data is cleared by the system and you only handle the navigation, quick example:

private ViewModelStoreOwner getStoreOwner() {
        NavController navController = Navigation
                .findNavController(requireActivity(), R.id.root_navigator_fragment);
        return navController.getViewModelStoreOwner(R.id.root_navigator);        
}


private void setUpSearchViewModel() {
    searchViewModel = new ViewModelProvider(getStoreOwner()).get(SearchViewModel.class);
}
martinseal1987
  • 1,862
  • 8
  • 44
  • 77