So, here is what I want.
The top level data is structured like below :
Section 1 Title -> Section 1 Content (List)
Section 2 Title -> Section 2 Content (List)
.
.
.
Section N Title -> Section N Content (List)
I want to display the section titles in the side menu which opens when the hamburger is icon is selected and when a specific section is selected, the side menu closes and the content for that section is loaded in the screen under the action bar.
So, the relevant UI components to be used are : Toolbar
, DrawerLayout
(for Side Menu) and Fragment
for loading the content in the center.
Now, I am trying to use the Navigation Components and get as much benefits of it as possible. The thing that I am unable to get to work is :
android menu resources
. I would like to use my own recycler view and load the menu dynamically.ContentFragment
to itself but I wasn't sure this was right because, there is no action inside it that takes the UI from one ContentFragment
to another ContentFragment
. It is a top level action from the side menu that loads a different ContentFragment
.Apart from the above 2 questions, I want to know if this is even a right candidate for using navigation components or is it better to use the traditional approach?
Implementing this is easily done with AndroidNavigation components.
1 - Dynamic DrawerLayout can be implemented by adding RecyclerView inside com.google.android.material.navigation.NavigationView
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="false">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvDrawer"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.navigation.NavigationView>
2 - Activity navigation init when using DrawerLayout
appBarConfiguration = AppBarConfiguration(
setOf(R.id.mainFragment),
binding.drawerLayout
)
binding.navView.setupWithNavController(navController)
// Setup action bar with nav controller
setupActionBarWithNavController(navController, appBarConfiguration)
3 - com.google.android.material.navigation.NavigationView
init
private fun loadDrawerItems(items: Array<String>) {
binding.rvDrawer.apply {
layoutManager = LinearLayoutManager(this@MainActivity)
adapter = DrawerAdapter(items, this@MainActivity)
}
}
4 - DrawerAdapter notify activity when the user clicks on the item
override fun onDrawerItemClick(value: String) {
binding.drawerLayout.closeDrawer(GravityCompat.START)
val direction = NavGraphDirections.refreshMainFragment(value)
navController.navigate(direction)
}
5 - Navigation
<?xml version="1.0" encoding="utf-8"?>
<navigation
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph"
app:startDestination="@id/mainFragment">
<fragment
android:id="@+id/mainFragment"
android:name="dh.sos.MainFragment"
android:label="Main fragment">
<argument
android:name="value"
app:argType="string"
android:defaultValue="Default value"/>
</fragment>
<action android:id="@+id/refreshMainFragment"
app:destination="@id/mainFragment"
app:popUpTo="@id/mainFragment"
app:popUpToInclusive="true">
<argument
android:name="value"
app:argType="string"
android:defaultValue="Default value"/>
</action>
</navigation>
app:popUpToInclusive="true"
indicates that popUpTo
destination should be also removed from the stack, which means every time when we call this action we'll get a new instance of Fragment
.
Full source code: https://github.com/dautovicharis/sos_android/tree/q_68441622