如何设置带有导航抽屉的导航组件? 如何在我的应用程序中使用它?
所有活动都可以用一个活动完成吗?
如何仅使用一个Activity和具有动态工具栏可见性的片段来处理工具栏可见性。另外,还有一些碎片需要关闭抽屉并使其无法使用。
此问题是一个自我解答的问题,它比实际的质量检查更能用作教程。
答案 0 :(得分:1)
如何设置带有导航抽屉的导航组件?
如何在应用程序中使用它?
在导航组件方面,导航抽屉的设置略有不同。
注意,如果使用抽屉式导航创建新应用,则不需要当前教程。但是,我将解释一些在这里可能看起来很奇怪的事情,以及如果您决定在应用程序的后期添加抽屉的话
首先,您需要设置activity_main.xml
和MainActivity
以便为导航架构做好准备:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<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="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
app_bar_main
只是:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
content_main
是将要保存您的片段的位置:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/app_bar_main">
<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:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
您应该了解的事情:活动中不得在AndroidManifest.xml
上设置AppBar:
android:theme="@style/AppTheme.NoActionBar"
如果您在app:menu="@menu/activity_main_drawer"
标记中注意到NavigationView
,则片段名称应与mobile_navigation.xml
中的片段名称相同:
<group android:checkableBehavior="single">
<item
android:id="@+id/homeFragment"
android:icon="@drawable/ic_menu_camera"
android:title="@string/menu_home" />
<item
android:id="@+id/galleryFragment"
android:icon="@drawable/ic_menu_gallery"
android:title="@string/menu_gallery" />
<item
android:id="@+id/slideshowFragment"
android:icon="@drawable/ic_menu_slideshow"
android:title="@string/menu_slideshow" />
<item
android:id="@+id/toolsFragment"
android:icon="@drawable/ic_menu_manage"
android:title="@string/menu_tools" />
</group>
<item android:title="Communicate">
<menu>
<item
android:id="@+id/shareFragment"
android:icon="@drawable/ic_menu_share"
android:title="@string/menu_share" />
<item
android:id="@+id/sendFragment"
android:icon="@drawable/ic_menu_send"
android:title="@string/menu_send" />
</menu>
</item>
</menu>
这样,下面将要解释,因此无需调用onCreateOptionsMenu
来检测点击。 Android团队已经为我们解决了这个问题。请按照下面的操作。
直到现在,这与我们实际所做的常规抽屉设置没有太大差异。但是,我们需要在应用程序的逻辑部分中进行一些配置。因此,让我们打开MainActivity.kt
。首先,您需要这些:
private var appBarConfiguration: AppBarConfiguration? = null
private var drawerLayout: DrawerLayout? = null
private var toolbar: Toolbar? = null
private var navController: NavController? = null
之后,在您的onCreate
方法中:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar) //set the toolbar
drawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
navController = findNavController(R.id.nav_host_fragment)
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.homeFragment,
R.id.galleryFragment,
R.id.slideShowFragment,
R.id.toolsFragment,
R.id.shareFragment,
R.id.sendFragment,
R.id.loginFragment,
R.id.phoneConfirmationFragment
), drawerLayout
)
setupActionBarWithNavController(navController!!, appBarConfiguration!!) //the most important part
navView.setupWithNavController(navController!!) //the second most important part
//other things unrelated
}
让我们看看这里发生了什么:
首先,您需要引用navController
。 AppBarConfiguration
只是一个类,其中包含将作为顶级目的地打开的片段。这意味着将在它们之后打开的片段将从片段返回堆栈释放当前片段。重要的是告诉AppBarConfiguration
我们也有一个抽屉(在构造函数中作为参数传递)。
在下面,您将有一个名为onSupportNavigateUp()
的方法:
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration!!) || super.onSupportNavigateUp()
}
此方法与向上后退按钮有关。但是,如果您有抽屉式导航功能,则不需要太多。当您在后堆栈中添加了很多片段(或至少两个)时,这真的很方便。
所有活动都可以用一个活动完成吗?
是的,绝对可以!但在条件导航方面仍然需要做更多的工作。就像您要显示不属于抽屉应用程序的片段时一样。但是Google仍然在这方面取得了巨大的进步。您可以参考条件导航here。
如何仅使用一个Activity和 具有动态工具栏可见性的片段。还有 我需要关闭抽屉并使其无法使用的碎片。
您可以使用addOnDestinationChangedListener
中的navController
:
navController.addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.loginFragment, R.id.registerFragment, R.id.phoneConfirmationFragment -> {
toolbar?.visibility = View.GONE
drawerLayout?.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
}
else -> {
toolbar?.visibility = View.VISIBLE
drawerLayout?.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
}
}
}
现在您的应用程序上有一个抽屉和导航组件。