敞开成长之旅!这是我参加「日新计划 2 月更文应战」的第 19 天,点击查看活动概况

前言

本篇主要是为了弥补上一篇(安卓组件学习——NavigationView导航视图 – ())缺少的前置内容,由于之前我一向认为NavigationView便是咱们的滑动菜单,可是到布局部分才发现,咱们是运用了DrawerLayout抽屉布局与NavigationView导航视图,一起组合成滑动菜单(实现侧滑交互体验)。

正文

废话不多说,咱们直接开写,先上咱们的布局,将一般的activity_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"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    </FrameLayout>
</androidx.drawerlayout.widget.DrawerLayout>

咱们能够看到与之前的布局不同,咱们运用了DrawerLayout抽屉布局作为最外层,在帧布局里咱们将ToolBar作为它的子布局,这便是整体的布局结构,接下来咱们顺次介绍。

ToolBar的运用

首先是ToolBar,其实便是标题栏,不过与ActionBar不一样,ActionBar只能位于Activity的顶部,而ToolBar则扩展性更高,更为灵活。

要运用ToolBar,咱们得了解标题栏为何会默认显现,其实这源于咱们为项目指定的主题:

安卓UI组件开发学习——抽屉布局DrawerLayout和标题栏Toolbar
在清单文件中咱们会指定咱们的主题,而其就定义在咱们的res/values/theme.xml文件中:

安卓UI组件开发学习——抽屉布局DrawerLayout和标题栏Toolbar
DarkActionBar代表咱们采用了深色的ActionBar主题,这就会为咱们项目的页面带上ActionBar标题栏,当然,咱们现在项目还有一个values-night文件夹是放置夜晚主题的:

安卓UI组件开发学习——抽屉布局DrawerLayout和标题栏Toolbar

由于咱们要运用ToolBar来替代原有的ActionBar,所以咱们先把主题换成不带ActionBar的NoActionBar:

<style name="Theme.MaterialDemo" parent="Theme.MaterialComponents.Light.NoActionBar">

Light.NoActionBar是淡色主题,即主体部分为淡色而陪衬部分为深色,而不带Light的NoActionBar是深色主题。

设置好这些之后,咱们就能在之前的布局代码中运用咱们的ToolBar,这儿对之前的代码中的特点进行一些解说,咱们能够看到app:xxx这种特点写法,这是为了兼容老体系,由于有的特点特别是Material特点是老体系不存在的,为了兼容咱们就不能再用android:xxx这种写法,而ToolBar布局里的android:theme特点是让咱们为ToolBar单独指定深色主题,这就能和其他没运用ToolBar的页面区分开,但这时假如ToolBar上有菜单按钮,这时弹出的菜单也会变成深色,这就看着很不舒畅,所以咱们又运用app:popupTheme去设置弹出的菜单项为淡色主题。

接着咱们在Activity中运用该ToolBar:

setSupportActionBar(binding.toolbar)

很简略,就一句代码咱们放入onCreate()办法中即可,即把ToolBar的实例传入setSupportActionBar办法中。

此外,咱们标题栏中的文字内容也是能够改动的,回到清单文件AndroidManifest.xml,咱们为该activity标签加上label标签指定咱们想要的文字内容即可。

不过现在的ToolBar过于单调,所以咱们可认为其加一些小组件,这和之前的Menu做法相似(安卓开发基础——Menu菜单的运用 – ()),咱们在menu文件夹里去创立一个新的menu资源文件toolbar.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/backup"
        android:icon="@drawable/ic_backup"
        android:title="Backup"
        app:showAsAction="always" />
    <item
        android:id="@+id/delete"
        android:icon="@drawable/ic_delete"
        android:title="Delete"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/settings"
        android:icon="@drawable/ic_settings"
        android:title="Settings"
        app:showAsAction="never" />
</menu>

这儿咱们有新的特点 app:showAsAction用来设置按钮显现方位,别离有always表明永久显现在toolbar中但屏幕方位不行就不显现,而ifRoom则是假如屏幕够就显现在toolbar上,不行就折叠到菜单中显现,最后的never则是一向显现在菜单中,要注意的是,咱们的按钮在Toolbar上就只会显现图片,而菜单中则只会显现文字,接着咱们在Activity中与Menu操作相似,复写咱们的onOptionsItemSelected办法来对按钮操控点击事情等,复写咱们的onCreateOptionsMenu办法去载入咱们的toolbar:

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    menuInflater.inflate(R.menu.toolbar, menu)
    return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
    when (item.itemId) {
        android.R.id.home -> binding.drawerLayout.openDrawer(GravityCompat.START)
        R.id.backup -> Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show()
        R.id.delete -> Toast.makeText(this, "You clicked Delete", Toast.LENGTH_SHORT).show()
        R.id.settings -> Toast.makeText(this, "You clicked Settings", Toast.LENGTH_SHORT).show()
    }
    return true
}

DrawerLayout抽屉布局的运用

这个更为简略,并且最好和NavigationView组合运用,否则款式太丑,在布局中咱们在文章正文第一个代码中已经看到便是写在最外层,然后便是一些特点操控,可是是写在第二个子控件上的(第一个是里边有ToolBar的FrameLayout),比如咱们上篇说的NavigationView:

<com.google.android.material.navigation.NavigationView
    android:id="@+id/navView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:menu="@menu/nav_menu"
    app:headerLayout="@layout/nav_header"/>

咱们设置了android:layout_gravity=”start”,这是必须指定的,由于这是用来告知DrawerLayout滑动菜单是在屏幕的左边仍是右边,即left左边,right右边,而咱们的start是根据体系设置的语言习惯的,咱们的汉语便是从左到右,即start为左,而阿拉伯语则从右到左,所以和咱们也正好相反,start就变成右边。

设置好布局,咱们Activity也要调整相应代码:

supportActionBar?.let {
    it.setDisplayHomeAsUpEnabled(true)
    it.setHomeAsUpIndicator(R.drawable.ic_menu)
}

首先让咱们的滑动菜单图标显现出来,然后和Menu一样复写咱们的onOptionsItemSelected办法,运用openDrawer办法传入GravityCompat.START让图标显现在最左边(开端)而不是ToolBar的Home返回按钮。

这样一来咱们就完成了整个滑动菜单,结合上篇的NavigationView,完好的Activity代码如下:

package com.example.materialdemo
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.core.view.GravityCompat
import com.example.materialdemo.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
    lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setSupportActionBar(binding.toolbar)
        supportActionBar?.let {
            it.setDisplayHomeAsUpEnabled(true)
            it.setHomeAsUpIndicator(R.drawable.ic_menu)
        }
        binding.navView.setCheckedItem(R.id.navCall)
        binding.navView.setNavigationItemSelectedListener {
            binding.drawerLayout.closeDrawers()
            true
        }
    }
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.toolbar, menu)
        return true
    }
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            android.R.id.home -> binding.drawerLayout.openDrawer(GravityCompat.START)
            R.id.backup -> Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show()
            R.id.delete -> Toast.makeText(this, "You clicked Delete", Toast.LENGTH_SHORT).show()
            R.id.settings -> Toast.makeText(this, "You clicked Settings", Toast.LENGTH_SHORT).show()
        }
        return true
    }
}

最终的效果如下:

安卓UI组件开发学习——抽屉布局DrawerLayout和标题栏Toolbar

# 总结 总算把完好的滑动菜单给整出来了,挺有意思,也算是咱们的UI组件学习的第一阶段完毕了。