In this chapter of the Navigation Component Android tutorial we are going to learn how to save the state of the fragment using ViewModel.
This tutorial is about how to use the JetPack Navigation Component to handle the fragment and activity navigations, argument and actions in our app centralized. The sample app contains 5 fragments, the main activity and a Navigation Drawer.
In the very last chapter we have added the Navigation Drawer and we implemented the top-level fragments as well. In this chapter we are going to learn how to save the state of the fragments using a ViewModel.
We are going to save the content of an EditText in a variable, which is declared in a ViewModel. Then, if we navigate back to this fragment, the content should be still there.
So let’s start coding. 😎
If you haven’t done the previous chapters, then from GitHub you can download the starter project for this chapter.
Before we start this chapter, we have to talk about a bit about ViewModel.
The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.
If you are not familiar with ViewModel, then it is recommended to check out the official documentation: ViewModel
Step 1 – Create the ViewModel
In this project, we are going to create the ViewModels next to the Fragment classes. It means, that the ViewModel classes gonna be located in the fragment package either.
To use the features of the ViewModel::class, we have to extend our new class with ViewModel(), like on the code snippet below.
Extend with ViewModel
After that, we will create a String variable, which will hold the content of the EditText.
var fragment2EditText: String? = null
That’s it. Now you can close the Fragment_2_ViewModel::class. We won’t do any changes there.
Step 2 – Save the state of the fragment
Thanks to navGraphViewModels(), the extended inline function for Fragment, we can get the instance of Fragment_2_ViewModel with one line of code. So, as a member variable copy and paste this line of code into the Fragment_2_ViewModel::class.
Save the data
Fragments have lifecycle either, like the activities. It means, depending on the state of the fragment, various methods will run. In our case, we are going to save the data to the ViewModel, when the fragments are destroyed. So, it will be done in the onDestroyView() method.
Now, press control+o and start typeing onDestroyView. If you could find the method, select it and click on the OK button.
After the call of the super class, we are going to save the string content of the EditText, which looks like this:
fragment2ViewModel.fragment2EditText = et_fragment_2.text.toString()
Retrieve the data
Finally, we can get back the data from the ViewModel. We are going to do that inside of the onViewCreated() method, when view is fully created.
Copy and paste these lines at the end of the method.
Retrieve the data
Because, we have declared the fragment2EditText as a nullable variable, we should call on it the .let lambda. It means, when the variable is null, then this lines won’t be executed. So, we can avoid the NullPointerException.
Run the app
Now run the app. If you open the Fragment_2 and write something in the EditText and if you navigate away from the fragment, then you come back, the text should be in the EditText.
Good job! 😎
The source code is available on GitHub
I hope the description was understandable and clear. But if you have still questions, then leave me comments below! 😉
Have a nice a day! 🙂