Problems covered in this chapter |
|
In this chapter we want to realise the display of the genders, which is shown when the user taps the menu item ”Gender” in the main menu. The display is done in a separate fragment GendersFragment.kt, whose user interface (UI) is defined in the layout file fragment_genders_list.xml. This XML file essentially consists of a RecyclerView element that fills its contents with the help of the additional layout file gender_item.xml and the adapter GenderItemAdapter.kt. Parallel to the fragment GendersFragment.kt we also create a ViewModel GendersListViewModel.kt. As already familiar from the previous chapters, we also have to extend our build.xml file and our navigation graph with additionally required elements.
With these additional dependencies, we enable RecyclerViews and CardViews, which are used to display our data from the database in the form of scrollable lists. We also activate DataBinding.
For the uniform display of data from the database in RecyclerViews we use a few styles, so we extend themes.xml with the above lines.
In our globally accessible class GlobalAppStore we define a variable _showInactive that reflects whether deactivated elements should be displayed or not (can be set in the settings).
In the class GendersListViewModel() we define the LiveData variable genders, which returns all genders contained in the database. The value 1L is passed to the getAllGenders() method so that the dummy value ”—” is not displayed in our RecyclerView. And depending on the variable showDeactivated, deactivated genders are displayed or not.
Furthermore, the ViewModelFactory GendersListViewModelFactory is defined in the same file, which gets our GenderDao class as a parameter, so that we can access the database in the ViewModel.
As can be seen in the ViewModel file GendersListViewModel above, it inherits from BaseViewModel.kt, a class into which we put variables and methods used in many ViewModel classes.
The MutableLiveData, its associated LiveData variables and the corresponding methods are used for navigation purposes. With their help, the fragments and their associated ViewModels inform each other whether a user has tapped a certain button (e.g. ’Add’ button) and therefore a new fragment must be displayed.
Later, we extend this basic class with many more variables and methods that are needed again and again in our ViewModels.
The layout file gender_item.xml defines how our gender elements from the database are displayed in the RecyclerView. For this purpose, we use a CardView that is visually equipped by means of styles previously defined in themes.xml. In this case, only the name of the gender is displayed (e.g. ”female”). In later item files, the display will be somewhat more extensive, in particular images will be used in the display. The data binding variable gender is defined by means of the data-element, which we access a little further down in the code for our GenderItemAdapter.
In fragment_genders_list.xml, a RecyclerView is used to display our genders. By means of the data-element, the variable viewModel is defined, which we access in the code in our fragment FragmentGendersList.kt, which we will deal with next.
Here we first initialise the data binding and our GendersListViewModel, which we create via the previously defined ViewModelFactory, which we pass our Genders-DAO class to when we call it. Then our Genders adapter is initialised and assigned to our RecyclerView in fragment_genders_list.xml using data binding. The activateAddFAB() method is defined in the Bais class BaseFragment.kt, which we describe a little further down - this method ensures that the FloatingActionButton for adding new elements (a plus symbol) is displayed at the bottom of the screen. This FAB is defined in activity_main.xml and is invisible there by default. Furthermore, our fragment observes the LiveData variable genders defined in the ViewModel: If this was filled with gender values from the database, the fragment is informed of this and we can pass the list with all gender values (male, female, diverse) to the Genders adapter. In the fragment method onDestroyView(), we call the method deactivateAddFAB(), which sets the FAB, which was previously set to visible, back to invisible.
As can be seen in the fragment file GendersListFragment above, it inherits from BaseFragment.kt, a class into which we put variables and methods that are used in many of our fragment classes. It is thus similar to our BaseViewModel class, which does the same for our ViewModels.
For now, only our two methods for showing and hiding a floating action button are defined there. Later, we will extend this basic class with lots of additional variables and methods. Next, we need an adapter to display our gender data in the RecyclerView.
This adapter code is essentially taken from Head First Android Programming and is very similar in structure for all our data classes. Only the code in the bind method of the GenderItemViewHolder is worth mentioning: By means of DataBinding, the variable gender from gender_item.xml is accessed here and it is checked whether the displayed element has been deactivated by the user. If this is the case, the item is displayed in the list with shading. The additional class GenderDiffItemCallback is used so that the adapter can decide whether two elements are identical.
As a last step we have to extend our navigation file nav_graph.xml with our new fragment and define actions for the navigation transitions from the home fragment and back (either in the graphical editor or directly in the XML code):
With all these new files and extensions of existing files, the code should now rebuild and run on a (virtual) device. If you tap on the menu item ’Gender’ in the main menu, our three elements from the database are shown (see Figure 9.1). At the bottom right you can see the FAB with which we will be able to add a new gender in the next chapter.