Creating a truly custom NavDrawer is possible, with little tweaking to the components.
Here are the steps:
1 - No menu layout, just headerView
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view_end"
android:layout_width="match_parent"
android:layout_marginLeft="-64dp"
android:layout_marginStart="-64dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:fitsSystemWindows="true"
app:headerLayout="@layout/shop_list"
/>
Notice that i placed margin start and left to -64dp. That's to get the drawer layout to be full width.
2 - Disable NavigationMenuView's scroll
Even though we didn't put a menu layout, it's still created and we need to access it and disable the scroll. Because this view is instance of the RecyclerView, we just need to override it's layout manager and disable the vertical scroll.
private fun disableMenuScroll(navView: NavigationView) {
val navMenu = navView.getChildAt(0) as NavigationMenuView
navMenu.layoutManager = object : LinearLayoutManager(this) {
override fun canScrollVertically(): Boolean {
return false
}
}
}
3 - Set the header layout to be full height
Here we use reflection to get the presenter
from HeaderView
and from that presenter we get the LinearLayout
that holds our headerLayout. That LinearLayout
is the one that doesn't let our layout stretch to match parent. We just change the LayoutParams
for that LinearLayout and it's done.
private fun changeDrawerLayoutHeight(navView: NavigationView) {
/*With reflection get the navView's presenter*/
val field = navView.javaClass.getDeclaredField("presenter")
field.isAccessible = true
val presenter = field.get(navView) as NavigationMenuPresenter
/*From presenter, get the header layout field*/
val layoutField = presenter.javaClass.getDeclaredField("headerLayout")
layoutField.isAccessible = true
val headerLayout = layoutField.get(presenter) as LinearLayout
/*Set layout params on the HeaderLayout to match parent*/
val params = headerLayout.layoutParams
params.height = LinearLayout.LayoutParams.MATCH_PARENT
headerLayout.layoutParams = params
}
Where does this code execute?
In your Activity's onCreate
method. Here is the code needed to execute this:
val navView = findViewById<NavigationView>(R.id.nav_view_end)
disableMenuScroll(navView)
changeDrawerLayoutHeight(navView)
Hope this helps somebody!