In this chapter of the Navigation Component Android tutorial, we are going to learn how to open a dialog fragment and how to get back the result of the user’s action.
This tutoiral is about how to use the JetPack Navigation Component to handle centralized the fragment and activity navigations, arguments and actions in our app. The sample app contains 5 fragments, the main activity and a Navigation Drawer.
In the very last chapter we have learned about, how we can save the state of the fragment using a ViewModel.
For this chapter we have prepared a start project. This project contains already the RecyclerView and the new fragment, which will be the dialog fragment. Using this dialog we will add new items to the RecyclerView.
You can download or clone the starter project using the below link.
After the download open Android Studio. From the File menu select the Open option, then navigate to the folder where you have the downloaded project. Click OK and update the necessery plugins and the gradle.
Run the app
Unlike before, we are going to start this chapter with running the downloaded project.
If you navigate to Fragment_3, then you will see an empty screen with a FloatingActionButton, which currently doesn’t do enything. Believe me, this fragment contains already a RecyclerView, but its list is still empty.
This starter project contains some more files, then the end project from the last chapter.
- It has a new xml file, called item_recyclerview.xml. This represents a row in the RecyclerView.
- The next new thing is an adapter, which handels the data and the rows for the RecyclerView.
- The third new thing is the dialog fragment, which has the name of AddToDoFragment. This fragment will popup when we click on the FloatingActionButton.
- In the drawable folder are also some new images.
- The green, orange and red circle for the priorities
- A plus icon for the FloatingActionButton
I recommend you to check the source code by yourself either, because as an Android developer you should use in many cases RecyclerViews to show data for the user.
Step 1 – Add the dialog to the navigation graph
To start implement in our app the dialog, we have to add it to the navigation graph. So open the navigaion directory from the res folder. Inside of this folder should be the navigation_graph.xml. Remember? This file contains the directions, the actions and the arguments of the app.
To add the dialog fragment to the graph, click on the New Destination icon. You can find this icon, if you are in Split or in Desing view. You can change the view using the 3 icons at the top right corner of Android Studio.
After the positioning, select the fragment_3 in navigation graph. A blue circle will be visible in the center at the right side. Click on it and hold the mouse button until you connect it with the addToDoFragment.
If you are in split or in code view, then you should see the generated code for the addToDoFragment and for the action of fragment_3.
Note that the addToDoFragment got the <dialog> tag and not <fragment>. If you open from the fragments package the AddToDoFragment::class, then you should see, that this fragment is inhereted from DialogFragment::class. When you add a new fragment to the navigation graph, then it can recognize the inheritance of the fragment.
Step 2 – The ViewModel
Before we add the code, which will open the dialog, we should add a ViewModel to our app. This ViewModel will store temporarily the list of todos and it will notify the UI, when a new item has been inserted into the list.
So, as we have done it before many times, click with the right mouse button on the fragment package, then select New, then Kotlin file/class. Name the new file as “Fragment_3_ViewModel“.
Then extend the class with ViewModel().
In the ViewModel, we will have a MutableList, which will contian the list of todos. Then, we will create a MutableLiveData and a LiveData also. The LiveData will get back the value of the MutableLiveData, which will store the MutableList.
The 3 variables of the ViewModel
If the list of the todos has a separated variable, then we can handle easier the list of the RecyclerView and the code will be more transparent.
Next is the method, which will add the new todo for the list, when we click on the Ok button on the dialog.
Because every ToDo in our list has a unique Id, we will add the size of the list before we add the new ToDo to the list.
Then we will add to the MutableList the item.
Finally we will update the MutableLiveData as well.
Step 3 – Open the dialog fragment
The next step is to open the dialog. So open from the fragment package the Fragment_3::class.
As we have talked about earlier, we will open the dialog fragment using the FAB. The body of the click listener will contain the same code, what we have used, when we navigated between the fragments using the buttons.
Copy and paste the below code inside of the onCreateView() method.
The first row will find the NavController, which is the base class for Navigation Component to navigate to the destinations in our app.
The second row will navigate us to the dialog fragment using the action, what we have created in the navigation graph.
Run the app
Now run the app. If you navigate to the Fragment_3 and click on the FAB, then the dialog should popup. The action buttons still doesn’t do anything. The declarations will come in the the next steps.
Step 4 – The Cancel button
The easiest step is to close the dialog, because the click listener will contain only on line, which is the call of the dismiss() method.
For the implementation, open the AddToDoFragment::class from the fragment package, and add the below code to the onCreateView() method.
The click listener for the Cancel button
Step 5 – The Ok button
The Ok button will call the addNewTodo() method from the Fragment_3_ViewModel::class. As the only argument, we have to take over a ToDo object for the ViewModel. To do this, first we will call first the createToDo() method, which is already defined in the AddToDoFragment::class. This method will create the ToDo object from the EditTexts and RadioButtons.
Add this click listener also to the onCreateView() method.
The click listener for the Ok button
Step 6 – The observer
The last thing is the Observer. It means, when the LiveData in the ViewModel changes, then it will notify the user interface about the change. In our case the change can be done only, when we add a new ToDo to the list. When it does happen, then we should notify the RecyclerView. The notification method is already implemented in the ToDoAdapter, which is the refreshItem() method.
Check it out! 😉
The Observer will be in the onViewCreated() method of the Fragment_3::class, because we should observe the LiveData, when the UI is already created.
So copy and paste the below code after the onCreateView() in the Fragment_3::class.
First, we are going to updata the list of the item, then we have to notify the adapter about the changes.
Run the app
Finally our app is finished, and ready to run again. Now, if you click on the OK button, then it will be added to the RecyclerView.
The final 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! 🙂