Android 官方 Navigation Drawer

1. 概述
2. 添加依赖
3. 设计 layout/activity_main.xml
4. 构建 layout/drawer_header.xml
5. 定义 menu/drawer_item.xml
6. 显示汉堡包图标
7. 使状态栏透明
  7.1 去除 Actionbar
  7.2 v21 增加关于状态栏的属性
  7.3 设置 DrawerLayout 使用 fitsSystemWindow
  7.4 补充:动态改变 status bar 颜色
8. 总结

1. 概述

Navigation drawer 作为 Android Material Design 中主流的一种导航方式,当然受到 Google 的重视,所以,作为 MD 设计推出的实现部分,Android 更新了 support library 增加了关于 Navigation Drawer 的支持。

下面就来看看如何进行 Navigation Drawer 的构建。

2. 添加依赖

官方的 Navigation Drawer 需要用到 DrawerLayoutNavigationView,它们都在 support design 包下。

1
compile 'com.android.support:design:24.2.1'

这里不使用最新的 25.0.0 的原因在于,最新版在 UI Editor 渲染时存在 bug。Google 不愧是世界上最伟大的半成品公司。

3. 设计 layout/activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
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"
android:fitsSystemWindows="true"
tools:context="com.wafer.toy.github_client.ui.activity.MainActivity">

<!-- Your main content -->


<android.support.design.widget.NavigationView
android:id="@+id/navigation_drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/drawer_item"/>
</android.support.v4.widget.DrawerLayout>

需要注意的是,DrawerLayout 是布局的根目录,同时要设置 fitsSystemWindows="true",否则,将会覆盖掉顶部状态栏。

还有,注意要设置 NavigationViewlayout_gravity="start",否则不会生效。

4. 构建 layout/drawer_header.xml

一般来说,Nav Drawer 都需要有一个 header 来存放用户头像等等有关用户账户的概览信息。

所以我们还要定义一个 header 的布局,然后像上面一样,将其赋予 app:headerLayout

header 的布局注意满足 Material Design 即可;布局样式和摆放不限。

5. 定义 menu/drawer_item.xml

是时候给我们的 Nav Drawer 加上一点内容了,通过在 menu/drawer_item.xml 中定义相应的组件即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<menu xmlns:android="http://schemas.android.com/apk/res/android">

<group android:checkableBehavior="single">
<item
android:id="@+id/nav_home"
android:icon="@drawable/ic_drawer_home"
android:title="@string/nav_home" />
<item
android:id="@+id/nav_about"
android:icon="@drawable/ic_drawer_about"
android:title="@string/nav_about" />
<item
android:id="@+id/nav_settings"
android:icon="@drawable/ic_drawer_settings"
android:title="@string/nav_settings" />

<item
android:id="@+id/navigation_subheader"
android:title="@string/nav_sub_header">
<menu>
<item
android:id="@+id/navigation_sub_item_1"
android:icon="@drawable/ic_drawer_about"
android:title="@string/nav_sub_item_1" />
<item
android:id="@+id/navigation_sub_item_2"
android:icon="@drawable/ic_drawer_home"
android:title="@string/nav_sub_item_2" />
</menu>
</item>
</group>
</menu>

注意,项目的分界通过内嵌的 <menu> 来实现。

需要注意的是,官方的 nav drawer 中的 item 没有 ripple,只有长按才能显示。

最后我们再将这个 menu 赋到 NavgationViewapp:menu="@menu/drawer_item"

6. 显示汉堡包图标

Drawer 到这里就完全搭建好了,但是,没有汉堡包图标,用户就不知道我们的应有有个 Nav Drawer。所以,我们就需要给 toolbar 加上一个汉堡包图标来凸显 Nav Drawer 的存在。

在这里,我们需要进入到 java 文件中进行修改了,由于我用的是 Kotlin,这里使用 Kotlin 来做演示。

下面就是增加显示汉堡包的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class MainActivity : BaseActivity() {

private val actionBarDrawerToggle: ActionBarDrawerToggle by lazy { createActionBarDrawerToggle() }

override fun initView() {
initToolbar()
initActionBarDrawerToggle()
}

private fun initActionBarDrawerToggle() {
drawer_layout.addDrawerListener(actionBarDrawerToggle)
actionBarDrawerToggle.syncState()
}

private fun initToolbar() {
setSupportActionBar(toolbar)
}



private fun createActionBarDrawerToggle(): ActionBarDrawerToggle {
return ActionBarDrawerToggle(
this, drawer_layout, toolbar, R.string.open_drawer, R.string.close_drawer)
}

override fun getLayoutRes(): Int {
return R.layout.activity_main
}
}

首先,使用 DrawerLayout 对象和 toolbar 对象来构建一个 ActionBarDrawerToggle 对象;

然后让 ActionBarDrawerToggle 成为 drawer_layout 的一个接口;

最后设置 actionBarDrawerToggle.syncState() 即可。

7. 使状态栏透明

我们已经成功的构建出了一个 Navigation Drawer,但是,其显示出来的效果是这样的

而官方的 MD 规范上,状态栏的效果是半透明的。

所以,我们还要做一些额外的步骤来让我们的 Nav Drawer 更符合规范。

7.1 去除 Actionbar

这个步骤通常已经在初步搭建构架的时候就完成了。也就是说为 style.xml 增加如下两项:

1
2
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>

并且继承 Theme.AppCompact.Light.DarkActionBar

7.2 v21 增加关于状态栏的属性

value-21/style.xml 中,增加另外的两项:

1
2
3
4
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>

7.3 设置 DrawerLayout 使用 fitsSystemWindow

1
2
3
4
5
<android.support.v4.widget.DrawerLayout
...
android:fitsSystemWindows="true"
app:insetForeground="@color/inset_color"
>

OK,到这里就大功告成了!

7.4 补充:动态改变 status bar 颜色

如果你想动态改变状态栏颜色的话,也有相应的 Java 接口。

1
2
3
drawerLayout.setStatusBarBackgroundColor(ContextCompat.getColor(this, R.color.wierd_green));

drawerLayout.setScrimColor(ContextCompat.getColor(this, R.color.wierd_transparent_orange));

8. 总结

这样构造出来的 Nav Drawer 和 MaterialDrawer 不同的一个地方在于,Nav Drawer 是在设计层面上进行修改,而 MaterialDrawer 是在代码层面上进行修改,侵入性不强,不过也较为麻烦。

总的来说,如果要快速搭建,则选择 MaterialDrawer;
但是要选择使用清真的写法,那么 Nav Drawer 则会更好。

0%