安卓开发学习之DrawerLayout


为什么要使用导航抽屉?

Android 导航抽屉是一个滑动菜单,用于显示应用程序中的重要链接。 导航抽屉可轻松在这些链接之间来回导航。 默认情况下它是不可见的,需要通过向左滑动或在 ActionBar 中单击其图标来打开它。 其易用性如下:

  • 从活动左边缘滑动手指时,用户可以查看导航抽屉;
  • 如果应用具有不同的界面(超过六个),则建议使用导航抽屉;
  • 它使应用程序更具交互性和简洁性。

导航抽屉的组件构成

  • DrawerLayout 组件的实例,抽屉的父布局容器
  • 作为 DrawerLayout 的子级嵌入的 NavigationView 组件的实例,也就是抽屉主体
  • 菜单资源文件,其中包含要在导航抽屉中显示结构和内容;
  • 一个可选的布局资源文件,其中包含要显示在导航抽屉的标题部分中的内容;
  • 分配给 NavigationView 的侦听器,用于检测用户何时选择了一项;
  • 一个 ActionBarDrawerToggle 实例,一个按钮,用于将导航抽屉连接和同步到应用栏,通过点击打开导航抽屉;

导航抽屉的实现

  1. appbuild.gradle 文件中添加依赖: implementation 'com.google.android.material:material:1.0.0',点击 Sync Now 等待同步完成;

  2. layout 中创建两个布局文件:

    • content_main.xml,主布局文件
    • nav_header.xml,抽屉顶部布局

    res 新建文件夹 menu,并创建 nav_menu.xml 文件,构建抽屉菜单;

    之后在 styles.xml 文件中添加主题:

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

    AndroidManifest.xml 中,对 MainActivity 应用该主题:

    <activity android:name=".MainActivity"
              android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
  3. 重写 MainActivity 对应的布局文件 activity_main.xml,引入之前创建的 content_main.xml

    <?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/content_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"
                app:menu="@menu/nav_menu"/>
    
    </androidx.drawerlayout.widget.DrawerLayout>
  4. 编辑抽屉顶部 nav_header.xml 布局文件,布局仅是 app 的图标文件以及两行文字:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="#4CAF50"
            android:orientation="vertical"
            android:gravity="bottom"
            android:paddingLeft="15dp"
            android:paddingBottom="15dp">
    
        <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:srcCompat="@mipmap/ic_launcher"
                android:id="@+id/imageView"
                android:layout_marginBottom="15dp"/>
    
        <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Title"
                android:textColor="#FFFFFF"
                android:textStyle="bold"/>
    
        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="This is our navigation drawer"
                android:textColor="#FFFFFF"/>
    
    </LinearLayout>
  5. 编辑抽屉菜单布局文件 nav_menu.xml,值得注意的是,当在使用 icon 时,可以利用 Android Studio 生成,在项目导航栏右击,选择New => Vector Asset即可;

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
        <group>
            <item
                  android:id="@+id/nav_profile"
                  android:icon="@drawable/ic_profile"
                  android:title="Profile"/>
            <item
                  android:id="@+id/nav_messages"
                  android:icon="@drawable/ic_messages"
                  android:title="Messages"/>
            <item
                  android:id="@+id/nav_friends"
                  android:icon="@drawable/ic_friends"
                  android:title="Friends"/>
        </group>
    
        <item android:title="Account Settings">
            <menu>
                <item
                      android:id="@+id/nav_update"
                      android:icon="@drawable/ic_update"
                      android:title="Update Profile"/>
                <item
                      android:id="@+id/nav_logout"
                      android:icon="@drawable/ic_signout"
                      android:title="Sign Out"/>
            </menu>
        </item>
    </menu>
  6. 编辑 content_main.xml 主布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:app="http://schemas.android.com/apk/res-auto"
                  android:orientation="vertical"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent">
    
        <com.google.android.material.appbar.AppBarLayout
                      android:layout_height="wrap_content"
                      android:layout_width="match_parent"                                                         android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
            <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/ThemeOverlay.AppCompat.Light">
                <LinearLayout
                              android:layout_width="match_parent"
                              android:layout_height="match_parent"
                              android:orientation="horizontal"
                              android:gravity="center_vertical">
                    <TextView
                              android:layout_width="wrap_content"
                              android:layout_height="wrap_content"
                              android:text="Navigation Drawer"
                              android:textColor="#FFFFFF"
                              style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"/>
                </LinearLayout>
            </androidx.appcompat.widget.Toolbar>
    
        </com.google.android.material.appbar.AppBarLayout>
    
        <LinearLayout
                      android:layout_width="match_parent"
                      android:layout_height="match_parent"
                      android:orientation="vertical">
            <TextView
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:text="This is my content area."/>
        </LinearLayout>
    
    </LinearLayout>
  7. 最后编辑MainActivity.kt 文件,将视图绑定到业务逻辑:

    class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
        // 声明控件并在 onCreate() 中初始化
        lateinit var toolbar: Toolbar
        lateinit var drawerLayout: DrawerLayout
        lateinit var navView: NavigationView
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            toolbar = findViewById(R.id.toolbar)
            setSupportActionBar(toolbar)
    
            drawerLayout = findViewById(R.id.drawer_layout)
            navView = findViewById(R.id.nav_view)
    
            // 创建 ActionBarDrawerToggle 对象
            val toggle = ActionBarDrawerToggle(
                this, drawerLayout, toolbar, 0, 0
            )
            // 建立 DrawerLayout 和 ActionBarDrawerToggle 的关联
            drawerLayout.addDrawerListener(toggle)
            toggle.syncState()
            navView.setNavigationItemSelectedListener(this)
        }
    
        // 重载接口方法
        override fun onNavigationItemSelected(item: MenuItem): Boolean {
            when (item.itemId) {
                R.id.nav_profile -> {
                    Toast.makeText(this, "Profile clicked", Toast.LENGTH_SHORT).show()
                }
                R.id.nav_messages -> {
                    Toast.makeText(this, "Messages clicked", Toast.LENGTH_SHORT).show()
                }
                R.id.nav_friends -> {
                    Toast.makeText(this, "Friends clicked", Toast.LENGTH_SHORT).show()
                }
                R.id.nav_update -> {
                    Toast.makeText(this, "Update clicked", Toast.LENGTH_SHORT).show()
                }
                R.id.nav_logout -> {
                    Toast.makeText(this, "Sign out clicked", Toast.LENGTH_SHORT).show()
                }
            }
            drawerLayout.closeDrawer(GravityCompat.START)
            return true
        }
    }
    • ActionBarDrawerToggle:其构造函数为:

      ActionBarDrawerToggle(
          activity: Activity!,     
          drawerLayout: DrawerLayout!, 
          toolbar: Toolbar!,     // 没有 Toolbar 时省略
          @StringRes openDrawerContentDescRes: Int,   // 这两个参数与 Accessibility 服务有关,便于视力不好的用户使用
          @StringRes closeDrawerContentDescRes: Int)    // 感兴趣可以谷歌
    • syncState():将抽屉指示器/功能的状态与链接的DrawerLayout同步

    • closeDrawer():用Gravity.LEFT键关闭左抽屉,或用Gravity.RIGHT键关闭右抽屉。 也可以使用GravityCompat.STARTGravityCompat.END


文章作者: Mahoo Huang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Mahoo Huang !
评论
 上一篇
安卓开发学习之ResyclerView 安卓开发学习之ResyclerView
添加依赖除了引入recyclerview,还引入cardview,它将作为 recyclerview 的子布局 implementation "androidx.recyclerview:recyclerview:1.1.0" implem
2020-05-01
下一篇 
利用ADB将安卓投屏到电脑进行调试开发 利用ADB将安卓投屏到电脑进行调试开发
保证手机与电脑在同一个局域网下,然后查看手机的IP地址: 投屏准备数据线连接手机,并确保手机与电脑在同一个局域网下,然后查看手机的IP地址 通过设置-WLAN,查看当前WiF信息详细,查看IP地址 通过adb命令查看:adb shell
2020-04-27
  目录