android - 导航组件 - 导航抽屉的问题
问题描述
我实际上在我的应用程序中使用了新的架构组件,并且我已经设置了导航组件。我有一个导航抽屉,我想使用它。我已经设置好了,但我遇到了一些问题:
1 - 抽屉不会自行关闭。菜单工作并导航到正确的位置,但导航后不会关闭它。我必须自己添加一个destinationChangedListener 来关闭它。
navController.addOnDestinationChangedListener { _, _, _ ->
if (drawer_layout.isDrawerOpen(GravityCompat.START))
drawer_layout.closeDrawer(GravityCompat.START)
}
在codelabs中,抽屉会自行关闭,我真的不明白为什么。
2 - 向上按钮打开抽屉。当我导航到非顶级片段时,菜单图标变为向上箭头,但是当我单击它时,它会打开抽屉菜单,而不是返回上一个目的地。
3 我想为我的菜单中的某些项目设置点击自定义。我菜单上的所有按钮都不是用于导航到应用程序,我不知道在哪里可以覆盖 navController 的行为以告诉它在他无法导航时该怎么做。
这是相关代码:
ActivityMain.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/layout_app_bar"/>
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/app_navigation" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<include layout="@layout/layout_navigation_view"/>
</androidx.drawerlayout.widget.DrawerLayout>
</FrameLayout>
Layout_app_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:theme="@style/AppTheme.AppBarOverlay"
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/language_main_color"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
抽屉菜单.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="@+id/appAction" >
<item
android:id="@+id/bridgeFragment"
android:icon="@drawable/ic_home"
android:title="@string/home" />
<item
android:id="@+id/categoryFragment"
android:icon="@drawable/ic_categories"
android:title="@string/categories" />
<item
android:id="@+id/favoriteFragment"
android:icon="@drawable/ic_favorite"
android:title="@string/favorites" />
<item
android:id="@+id/unlimited"
android:icon="@drawable/ic_unlimited"
android:title="@string/dialog_ask_unlimited_title" />
<!--<item
android:id="@+id/settings"
android:icon="@drawable/ic_settings"
android:title="@string/settings" /> -->
</group>
<group android:id="@+id/globalAction">
<item
android:id="@+id/rate"
android:icon="@drawable/ic_rate"
android:title="@string/rate" />
<item
android:id="@+id/aboutFragment"
android:icon="@drawable/ic_about_me"
android:title="@string/about"/>
</group>
</menu>
MainActivity.kt (setupMenus() 和 setupView() 在 onCreate 中被调用)
override fun setupView(){
val host: NavHostFragment = supportFragmentManager
.findFragmentById(R.id.nav_host_fragment) as NavHostFragment? ?: return
val navController = host.navController
val drawerLayout : DrawerLayout? = findViewById(R.id.drawer_layout)
appBarConfiguration = AppBarConfiguration(
setOf(R.id.bridgeFragment, R.id.categoryFragment, R.id.favoriteFragment, R.id.aboutFragment),
drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
setupNavigationMenu(navController)
navController.addOnDestinationChangedListener { _, _, _ ->
if (drawer_layout.isDrawerOpen(GravityCompat.START))
drawer_layout.closeDrawer(GravityCompat.START)
}
}
fun updateHasMenu(hasMenu: Boolean) { this.hasMenu = hasMenu }
private fun setupNavigationMenu(navController: NavController) {
val sideNavView = findViewById<NavigationView>(R.id.nav_view)
sideNavView?.setupWithNavController(navController)
}
override fun onSupportNavigateUp(): Boolean {
return findNavController(R.id.nav_host_fragment).navigateUp(appBarConfiguration)
}
override fun setupMenus(){
setSupportActionBar(toolbar)
supportActionBar?.let {
it.setDisplayHomeAsUpEnabled(true)
it.setHomeAsUpIndicator(R.drawable.ic_menu)
}
}
解决方案
这就是您的第一个、第二个和第三个问题的全部工作代码。
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private lateinit var navController: NavController
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
navController = findNavController(R.id.nav_controller_fragment)
appBarConfiguration = AppBarConfiguration(navController.graph,drawer_layout)
setupActionBarWithNavController(navController,appBarConfiguration)
drawer()
setupNavigationMenu()
nav_view.setNavigationItemSelectedListener(this)
}
private fun drawer() {
drawer_layout.addDrawerListener(object :DrawerLayout.DrawerListener{
override fun onDrawerStateChanged(newState: Int) {
}
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
}
override fun onDrawerClosed(drawerView: View) {
}
override fun onDrawerOpened(drawerView: View) {
}
})
}
private fun setupNavigationMenu() {
nav_view.let {
NavigationUI.setupWithNavController(it, navController)
}
}
override fun onBackPressed() {
if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
drawer_layout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_settings -> true
else -> NavigationUI.onNavDestinationSelected(item,navController) || super.onOptionsItemSelected(item)
}
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
drawer_layout.closeDrawer(GravityCompat.START)
return when (item.itemId) {
R.id.nav_gallery -> true
else ->
NavigationUI.onNavDestinationSelected(
item,navController) || super.onOptionsItemSelected(item)
}
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
推荐阅读
- amazon-web-services - 断言您拥有外部服务的 AWS IAM 角色
- algorithm - (Hackerrank)(石头游戏)如果条件不明,我怎么能找到答案
- r - IBrokers 中的 reqHistoricalData 是否存在 from 和 to 论点?
- javascript - 无法创建反应应用程序
- php - 如何在没有凭据的情况下更改 MySQL max_connections_per_hour?
- io - 重磁盘 IO 会导致非磁盘 IO 线程变慢吗?
- python - 对于Python语言,单引号和双引号有什么区别
- python - 使用硒的xpath找不到twitter DM文本框
- javascript - 如何从.net接收两个ajax json数据
- github-actions - with 和 env 有什么区别