Android – Toolbar 上的 Navigation Drawer
来源:互联网 发布:华为的程序员 编辑:程序博客网 时间:2024/06/11 09:13
来源 http://blog.mosil.biz/2014/10/navigation-drawer-on-toolbar/
编辑推荐:稀土掘金,这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识、前端、后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过!
ToolBar的基础知识请先阅读:android:ToolBar详解(手把手教程)
在 Material Design 发布后,Google 也开始陆续更新了 Google app 的界面,让大家有个范例可以看。而过去大力推动的 actionbar 自然而然也成了众开发者观注的部份;其中的 up button(返回上一级) 的设置在前一篇所介绍的 Toolbar 也已看到。这边还未提到的一个部份是 material design 中有提到的人机交互效果,简言之,就是让使用者明显地感受到在操作 app 时,可以获得明显的回应,从而得到丰富地操作体验感;因此,在刚开始放出的几支 Google app 里,大家一定都有留意到开启 navigation drawer 时,up button 的旋转动画效果。
先来看看效果:
相信大家也都会很好奇这个效果要如何实现,会不会很麻烦?所幸,这个效果,被放进 support v7 之中,我们只要拿來用即可。在本篇中将分下列几个部份,来带大家轻松实现这种效果来。
本篇所使用到的程式码,请到 Github 下载。
1. 实作
我们马上从 navdrawer_deom_checkpoint0 开始 (这份代码其实在 android:ToolBar详解(手把手教程) 一文的自定义颜色一节完成的 toolbar_demo_checkpoint2),
在 activity_main.xml 中加入 DrawerLayout
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity">
- <android.support.v7.widget.Toolbar
- android:id="@+id/toolbar"
- ... />
- <android.support.v4.widget.DrawerLayout
- android:id="@+id/drawer"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:layout_below="@+id/toolbar">
- <!-- Content -->
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- ...
- </RelativeLayout>
- <!-- Side Drawer -->
- <LinearLayout
- android:id="@+id/drawer_view"
- android:layout_width="@dimen/navdrawer_width"
- android:layout_height="match_parent"
- android:layout_gravity="start"
- android:background="#88FFFFFF"
- android:orientation="vertical">
- </LinearLayout>
- </android.support.v4.widget.DrawerLayout>
- </RelativeLayout>
加入后,请记得将原本在 Toolbar 控件之前的 TextView 放到<!-- Content --> 部份,做 DrawerLayout 其中的內容界面,否则在忘记放入 Content 界面的状況下,关闭侧边栏时,会发生「java.lang.NullPointerException: Attempt to invoke virtual method ‘android.view.ViewGroup$LayoutParams android.view.View.getLayoutParams()’ on a null object reference
这样的错误讯息。
在 drawer_view 中,要记得 layout_gravity 设定成 start 或是 left 。
activity_main.xml 完整程式码请见 github。
再来,就是到 MainActivity.java 中去实作 DrawerLayout,部份程式码如下:
- private DrawerLayout mDrawerLayout;
- private ActionBarDrawerToggle mDrawerToggle;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- ...
- // 打開 up button
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
- // 實作 drawer toggle 並放入 toolbar
- mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close);
- mDrawerToggle.syncState();
- mDrawerLayout.setDrawerListener(mDrawerToggle);
- }
完成后,就可以看到如上方影像一样的效果了!
完整程式码请见:navdrawer_demo_checkpoint1
2. Side Drawer
一开始,Material Design 设计文档 中,其实是没有看到侧边栏的相关说明,一直到 2014.10 才以「Side Nav」之名,加述于导览文件之中。而这个定义中的 Side Nav 画面,其实跟原本在 actionbar 的阶段是不太一样的,drawer layout 会压在 toolbar 上,如下图:
目前在 Google app 的界面中,还是以前一种为多,而现下 (2014.10) 如同 material design 在 side nav 呈现的界面还不多。
接下来就用 navdrawer_demo_checkpoint1 做为这个阶段的开始往下进行,需要调整就只有界面 (activity_main.xml) 的部份:
- <android.support.v4.widget.DrawerLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/drawer"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- tools:context=".MainActivity">
- <!-- Content -->
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <android.support.v7.widget.Toolbar
- android:id="@+id/toolbar"
- ... />
- ...
- </RelativeLayout>
- <!-- Side Drawer -->
- <LinearLayout
- android:id="@+id/drawer_view"
- android:layout_width="@dimen/navdrawer_width"
- android:layout_height="match_parent"
- android:layout_gravity="start"
- android:clickable="true"
- android:background="#88FFFFFF"
- android:orientation="vertical">
- </LinearLayout>
- </android.support.v4.widget.DrawerLayout>
将 DrawerLayout 改到这个 layout 的 root 层,并将 toolbar 移到 content 的 layout 中,这样就可以达到这样的效果了。
需要注意的是地方在 Side 的 layout 要设定 clickable 的属性设定为 true,否则会在侧边栏打开的状况下,还能按到位于界面下方的 up button。
But!人生就是这个 but!
在前一阵子,Google 的设计师为 Google I/O 2014 设计了另外一种样式出来,差异请见下图:
嗯,简言之,状态栏是半透明的状态,而侧边栏可以被看到。要调整的地方有二,
一在 layout – activity_main.xml:
- <android.support.v4.widget.DrawerLayout
- ...
- android:fitsSystemWindows="true"
- ...>
- <!-- Content -->
- ...
- <!-- Side Drawer -->
- <LinearLayout
- ...
- android:fitsSystemWindows="true"
- ... >
- </LinearLayout>
- </android.support.v4.widget.DrawerLayout>
在 root 层的 drawer layout 跟 side drawer 的 layout 各别加上 android:fitsSystemWindows="true" 这个属性
另外一个要改的地方是在 v21/styles.xml
- <style name="AppTheme" parent="AppTheme.Base">
- ...
- <!--Status bar color-->
- <item name="android:statusBarColor">#88009688</item>
- </style>
加入一个有透明度的色码给 android:statusBarColor 这个状态列颜色设定属性。
这样就可以完成这个阶段的程式了。
完整程式码请见:navdrawer_demo_checkpoint2
3. 其他议题
Navigation icon 切换的效果,除了旋转以外,还有另外一种效果,请看下方的影像:
3.1 Navigation icon effect
左上角的切换效果变成线条的的聚合,同时 icon 的颜色也被改为黑色,这个设定只要在 /res/values/styles.xml 做如下设定
- <style name="AppTheme.Base" parent="Theme.AppCompat">
- ...
- <!--將新加入的風格 AppTheme.MyDrawerStyle 設定給 drawerArrowStyle 這個屬性-->
- <item name="drawerArrowStyle">@style/AppTheme.MyDrawerArrowStyle</item>
- </style>
- <!--加入一個新的 navigation drarwer 的風格-->
- <style name="AppTheme.MyDrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
- <!--將 spinBars 屬性設定為 false-->
- <item name="spinBars">false</item>
- <!--設定 drawer arrow 的顏色-->
- <item name="color">@android:color/black</item>
- </style>
先加入针对 navigation icon 设定的风格: AppTheme.MyDrawerArrowStyle ,其继承自 Widget.AppCompat.DrawerArrowToggle 这个风格。
以本范例来说,这个风格裡设定了两个属性:
spinBars
旋转效果
false。由此可之,其预设的旋转效果预设值就是 true 了。
color
设定 navigation icon 的颜色。
增加后,再回到 AppTheme.Base 风格中,将此风格设定给 drawerArrowStyle 即可看到效果了。
3.2 Shadows
在影像中,大家应该可以看到,这个范例中还有一处跟之前不同了,内容为 Hello world! 的 TextView 变成黑色了!哦!当然不是要为各位介绍这个以前就有属性。要请各位留意的是在 TextView 周围有一圈淡淡的影子,还有在 Toolbar 也因为下方的影子,看起来较有立体感。而这也就是在 Material design 中有提到的其中一个部份:Shadows。
在过去这个效果需要自己去设定 drawable,现在只要设定个属性即可。请到 activity_main.xml 中
- <!-- Content -->
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <android.support.v7.widget.Toolbar
- ...
- android:elevation="10dp"
- ... />
- <TextView
- ...
- android:elevation="10dp"
- android:background="@android:color/black"
- .../>
- </RelativeLayout>
最主要就是针对 android:elevation 这个属性设定,而这个属性的意义也如同其字面的意义,他是在承述相较于底层的高度而被创造出来的阴影。而另外,在这段程式码中,特别将 TextView 中的 android:background 也列出来的原因,就是要让大家知道,android:elevation 这个属性要能够生效,该介面元件的背景属性也需要设定哦!
完整程式码请见:navdrawer_demo_checkpoint3
4. 一点想法
新的 navigation drawer 在 material design 的 side nav 裡有著跟过去不同的样式,而在 Google app 中,包含文中提到那种新的呈现样式算来,共有三重风格。这应该也意谓著,以 Google 在 side nav 在 android app 的呈现上,给予了这些弹性在。换句话说,这样看来,目前看到的这三种样式在 android app 上来看,都可以算是 material design。
也许有人会问,那导览文件是写好玩的吗?以个人的观点来看,那个的确是一个规范,是 Google 想要在不同的平台上有一个共通的范畴得以依循。因此,相信未来在 Google 的产品中,于 web、iOS 以及其他装置的介面,都会以 material design 做为标准,而设计出统一的 Google app 的体验。
而在 android 装置上,嘿嘿…毕竟是 Google 定义的嘛~那自然这部份的弹性就多于其他平台喽。所以,私以为就别太过纠结于导览文件上的定义,只要符合目前所看到的三种样式,应该都可以被视 android 装置上的 material design 啦。大家也可以放宽心的运用这三种样式去做 android app 的设计喽。
当然,以上纯粹个人观点,不代表官方立场,除非有 Google 的人在本篇中给予留言,做认证喽 :
最後,附上本篇所有範例的程式連結,還請大家多多指教嘍。
- Android – Toolbar 上的 Navigation Drawer
- Android – Toolbar 上的 Navigation Drawer
- Android – Toolbar 上的 Navigation Drawer
- Android的导航抽屉---Navigation Drawer
- Android官方的SlidingMenu--Navigation Drawer
- Android官方的SlidingMenu--Navigation Drawer
- Android的导航抽屉---Navigation Drawer
- Android Navigation Drawer
- Android之Navigation Drawer
- Android学习 - Navigation Drawer
- Android Navigation Drawer
- Navigation Drawer的使用
- Android Navigation Drawer(导航抽屉)
- 关于android抽屉,navigation drawer
- Android Navigation Drawer(导航抽屉)
- Android 开发之Navigation Drawer
- android-Creating a Navigation Drawer
- Android开发模板------SlidingPaneLayout、Navigation Drawer的基本介绍
- hadoop原生版安装部署---3.hdfs
- HibernateSpatial4.3+postgresql的使用
- 一,Launch启动图片,隐藏上面的状态栏
- centos6.5 Building the main Guest Additions module
- 仿微信输入框静态
- Android – Toolbar 上的 Navigation Drawer
- 【数据结构】之 线性表详解
- sapui5不同View之间传参数的方法
- markdown如何打出双下标
- wenzahang
- 移动端html5图片上传方法【更好的兼容安卓IOS和微信】
- 修改studio的字体大小
- 给nginx自定义错误页面
- redis 集群常用命令