Skip to content

Instantly share code, notes, and snippets.

@nanofi
Last active October 27, 2019 04:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nanofi/af4d42aa1c03a9df12a47519cfa0c428 to your computer and use it in GitHub Desktop.
Save nanofi/af4d42aa1c03a9df12a47519cfa0c428 to your computer and use it in GitHub Desktop.
Workaround for fixing the issue where NavigationView does not correctly control `IsChecked` of the submenus
class Helper {
companion object {
fun setupWithNavController(navigationView: NavigationView, navController: NavController) {
navigationView.setNavigationItemSelectedListener { item ->
val handled = NavigationUI.onNavDestinationSelected(item, navController)
if (handled) {
val parent = navigationView.parent
if (parent is DrawerLayout) {
parent.closeDrawer(navigationView)
} else {
findBottomSheetBehavior(navigationView)?.setState(BottomSheetBehavior.STATE_HIDDEN)
}
}
handled
}
val weakReference = WeakReference(navigationView)
navController.addOnDestinationChangedListener(
object : NavController.OnDestinationChangedListener {
override fun onDestinationChanged(
controller: NavController,
destination: NavDestination, arguments: Bundle?
) {
val view = weakReference.get()
if (view == null) {
navController.removeOnDestinationChangedListener(this)
return
}
checkDestination(destination, view.menu)
}
})
}
private fun checkDestination(destination: NavDestination, menu: Menu) {
menu.forEach { item ->
if(item.hasSubMenu())
checkDestination(destination, item.subMenu)
else
item.isChecked = matchDestination(destination, item.itemId)
}
}
private fun matchDestination(destination: NavDestination, destId: Int): Boolean {
var currentDestination: NavDestination? = destination
while (currentDestination!!.id != destId && currentDestination.parent != null) {
currentDestination = currentDestination.parent
}
return currentDestination.id == destId
}
private fun findBottomSheetBehavior(view: View): BottomSheetBehavior<*>? {
val params = view.layoutParams
if (params !is CoordinatorLayout.LayoutParams) {
val parent = view.parent
return if (parent is View) {
findBottomSheetBehavior(parent as View)
} else null
}
val behavior = params.behavior
return if (behavior !is BottomSheetBehavior<*>) {
// We hit a CoordinatorLayout, but the View doesn't have the BottomSheetBehavior
null
} else behavior
}
}
}
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.nav_bookmark, R.id.nav_hold, R.id.nav_ranking, R.id.nav_search, R.id.nav_keyword
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
Helper.setupWithNavController(navView, navController)
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
@nanofi
Copy link
Author

nanofi commented Oct 27, 2019

This code is almost the same as NavigationUI.setupWithNavController(NavigationView, NavController) except I added checkDestination.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment