如何在Android中使用Navigation Drawer设置Navigation Component? [英] How to set up Navigation Component with Navigation Drawer in Android?

查看:55
本文介绍了如何在Android中使用Navigation Drawer设置Navigation Component?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何设置带有导航抽屉的导航组件?如何在我的应用程序中使用它?

How do I set up navigation component with navigation drawer? How do I use it in my app?

所有活动都可以用一个活动完成吗?

Can everything be done with one Activity?

如何仅使用一个Activity和具有动态工具栏可见性的片段来处理工具栏可见性.另外,还有一些碎片需要关闭抽屉并使其无法使用.

How do I handle toolbar visibility with just one Activity and fragments which have a dynamic toolbar visibility. Also, there are fragments which I need to close the drawer and make it inaccessible.

这个问题是一个自我解答的问题,它比实际的质量检查更能用作教程.

推荐答案

如何设置带有导航抽屉的导航组件?

How do I set up navigation component with navigation drawer?

如何在我的应用程序中使用它?

How do I use it in my app?

在导航组件方面,导航抽屉的设置略有不同.

The navigation drawer set up differs a little when it comes to Navigation component.

注意,如果使用抽屉式导航创建新应用,则不需要当前教程.但是,我将解释一些在这里可能看起来很奇怪的事情,以及如果您决定在应用程序的后期添加抽屉的话

首先,您需要设置 activity_main.xml MainActivity 以准备好导航架构:

First, you need to set up your activity_main.xml and MainActivity to be ready for the Navigation Architecture:

<?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:

Things you should know: The activity mustn't have a AppBar set on AndroidManifest.xml:

android:theme="@style/AppTheme.NoActionBar"

如果您在 NavigationView 标记中注意到 app:menu ="@ menu/activity_main_drawer" ,则片段名称应与中的片段名称相同mobile_navigation.xml :

If you notice app:menu="@menu/activity_main_drawer" in the NavigationView tag, the fragment names should be the same that they are inside the 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团队已经为我们解决了这个问题.请按照下面的操作.

This way, with what is going to be explained below there will be no need to call for onCreateOptionsMenu to detect the clicks. Android team has already solved that for us. Follow below.

直到现在,这与我们实际上所做的常规抽屉设置没有太大差异.但是,我们需要在应用程序的逻辑部分中进行一些配置.因此,让我们打开 MainActivity.kt .首先,您将需要这些:

Until now, this doesn't differ too much from the usual drawer set up we actually do. But, there are some configurations we would need to do in the logic part of the app. So let's open MainActivity.kt. First you will need these:

  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
    }

让我们看看这里发生了什么:

Let's see what's going on here:

首先,您需要对 navController 的引用. AppBarConfiguration 只是一个类,其中包含将要作为顶级目标打开的片段.这意味着将在它们之后打开的片段将从片段返回堆栈释放当前的片段.重要的是要告诉 AppBarConfiguration 我们也有一个抽屉(在构造函数中作为参数传递).

First you would need a reference to the navController. The AppBarConfiguration is just a class which holds the fragments that are going to be opened as top level destinations. Which means that the fragment which is going to be opened after them would release the current one from the fragment back stack. It's important to tell to the AppBarConfiguration that we have a drawer also (passed as a parameter in the constructor).

在下面,您将有一个名为 onSupportNavigateUp()的方法:

Down below you would have a method called onSupportNavigateUp():

override fun onSupportNavigateUp(): Boolean {
        val navController = findNavController(R.id.nav_host_fragment)
        return navController.navigateUp(appBarConfiguration!!) || super.onSupportNavigateUp()
    }

此方法与向上后退按钮有关.但是,如果您有抽屉式导航功能,则不需要太多.当您在后堆栈中添加了很多片段(或至少两个)时,这真的很方便.

This method has to do with the up back button. But you won't need it too much if you have drawer navigation. This really comes in handy when you have a lot of fragments added on the backstack (or at least two).

所有活动都可以用一个活动完成吗?

Can everything be done with one Activity?

是的,绝对可以!但在条件导航方面仍然需要做更多的工作.就像您要显示不属于抽屉应用程序的片段时一样.但是Google仍然在这方面取得了巨大的进步.您可以在此处参考.

Yes, definitely! but still it requires a little bit more work when it comes to conditional navigation. Like when you want to show fragments which are not part of your drawer app. But still Google has done a huge progress with it. You can refer to conditional navigation here.

如何仅通过一个Activity处理工具栏的可见性,具有动态工具栏可见性的片段.还有我需要关闭抽屉并使其无法使用的碎片.

How do I handle toolbar visibility with just one Activity and fragments which have a dynamic toolbar visibility. Also, there are fragments which I need to close the drawer and make it inaccessible.

您可以从 navController 使用 addOnDestinationChangedListener :

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)
                }
            }
        }

现在您的应用程序上有一个抽屉和导航组件.

Now you have a drawer and navigation component on your app.

这篇关于如何在Android中使用Navigation Drawer设置Navigation Component?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆