Android 5.0 Lollipop是曾经最著名的Android发布之一,这样说很大一部分原因是材料设计的引入,而材料设计则是一种刷新了整个Android体验的设计语言。这个详细说明是开始适应材料设计的好地方,但是也可以理解,材料设计对于开发人员来说是一个巨大的挑战,尤其是关注应用向后兼容的开发人员。有了来自Android Design Support Library的些许帮助,给所有的开发人员和所有Android 2.1+的设备带来了大量非常重要的材料设计构件。你将发现诸如抽屉导航视图,带有浮动标签的EditText,FloatingActionButton,snackbar,tab和把他们联系在一起的动作和滚动框架。
NavigationView
导航抽屉能够成为应用内标识和导航的非常重要的焦点,设计的一致性也对于应用的导航是多么地容易产生了重要的影响,尤其是对于小白用户。NavigationView通过提供一种框架,使得这种想法更加容易实现。而这个框架则满足了你对于导航抽屉和通过menu资源填充导航item的能力的需要。
你可以像这样在布局文件中把NavigationView作为DrawerLayout的抽屉内容视图:
1 <android.support.v4.widget.DrawerLayout 2 xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:fitsSystemWindows="true"> 7 <!-- your content layout --> 8 <android.support.design.widget.NavigationView 9 android:layout_width="wrap_content" 10 android:layout_height="match_parent" 11 android:layout_gravity="start" 12 app:headerLayout="@layout/drawer_header" 13 app:menu="@menu/drawer"/> 14 </android.support.v4.widget.DrawerLayout>
你可能会注意到NavigationView的两个属性:app:headerLayout控制用于header的可选布局。app:menu是用于填充导航项的菜单资源,同时也可以在运行时更新导航项内容。NavigationView为你提供状态栏的纱布保护,以确保NavigationView与状态栏在API 21+的设备上准确地进行交互。
最简单的抽屉菜单是一系列checkable菜单项的集合:
1 <group android:checkableBehavior="single"> 2 <item 3 android:id="@+id/navigation_item_1" 4 android:checked="true" 5 android:icon="@drawable/ic_android" 6 android:title="@string/navigation_item_1"/> 7 <item 8 android:id="@+id/navigation_item_2" 9 android:icon="@drawable/ic_android" 10 android:title="@string/navigation_item_2"/> 11 </group>
checked项将会在导航抽屉里面高亮显示,以确保用户知道哪个导航项在当前情况下是选中的。
你也可以在menu中使用subheader来分割导航项群组:
1 <item 2 android:id="@+id/navigation_subheader" 3 android:title="@string/navigation_subheader"> 4 <menu> 5 <item 6 android:id="@+id/navigation_sub_item_1" 7 android:icon="@drawable/ic_android" 8 android:title="@string/navigation_sub_item_1"/> 9 <item 10 android:id="@+id/navigation_sub_item_2" 11 android:icon="@drawable/ic_android" 12 android:title="@string/navigation_sub_item_2"/> 13 </menu> 14 </item>
你可以通过使用setNavigationItemSelectedListener()方法设置OnNavigationItemSelectedListener来获取已选中项的回调。它向你提供了被点击的MenuItem,以允许你处理选中事件,改变被选中状态,加载新的内容,通过代码关闭抽屉,或者任何你想要的事件。
可编辑文本的浮动标签
即便是最低下的EditText,在材料设计中也有改进的空间。在单个EditText首个字符输入之后,提示文本将会被隐藏,但是现在你可以把提示文本包裹在TextInputLayout里面,使得提示文本成为EditText上面的浮动标签,以确保用户从不丢失他们正在输入的上下文环境。
除了展示提示信息之外,你也可以通过调用setError()在EditText下面展示错误信息。
FloatingActionButton
漂浮动作按钮是一个在交互界面上提供基本动作的圆形按钮。Design包中的FloatingActionButton向你提供了单个一致的实现,默认情况下是涂上了主题中的colorAccent颜色。
漂流动作按钮除了有正常尺寸外,它还在拥有其它元素时可视化持续性非常挑剔的时候支持迷你尺寸(fabSize=”mini”)。因为FloatingActionButton扩展自ImageView,所有的你也可以使用android:src,或者其它任何诸如setImageDrawable()的方法来控制显示在FloatingActionButton里面的图标。
Snackbar
对操作提供轻量级的快速反馈是使用snackbar的绝佳时机。Snackbar展示在屏幕询问,包含了支持可选的单动作的文本。它们在给定时间之后自动超时,并以动画的形式离开屏幕。此外,用户也可以在超时之前通过滑动将其消失。
拥有通过滑动或者动作来与之交互的能力,Snackbar显然拥有比toast更加强大的能力,和别外一种轻量级的反馈机制。然而,你会发现API其实对你而言非常熟悉:
1 Snackbar 2 .make(parentLayout, R.string.snackbar_text, Snackbar.LENGTH_LONG) 3 .setAction(R.string.snackbar_action, myOnClickListener) 4 .show(); // Don’t forget to show!
你会注意到make()方法的第一个参数View的使用—Snackbar将尝试找到自己视图的恰当父视图来确保自己显示在底部。
Tabs
在应用中通过Tab在不同视图中间切换对于材料设计而言并非一个新的概念,他们等同于主页的顶级导航模式或者在应用内组织不同群组的内容(例如,不同风格的音乐)。
Design包中的TabLayout既然实现了固定Tab,也实现了滚动Tab。对于前者,视图的宽度在所有Tab之间等分,而对于后者,Tab并没有统一的尺寸,而且可以横向滚动。Tab可以通过代码添加:
1 TabLayout tabLayout = ...; 2 tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
然而,如果你正在使用ViewPager在Tab之间横向分页,你可以直接从PagerAdapter的getPageTitle()方法创建tab,然后使用setupWithViewPager()方法将ViewPager和Tab联系起来。这样就确保了tab选中事件更新了ViewPager,而分页更新了选中的tab。
CoordinatorLayout,动作和滚动
不只独特的视角是材料设计中的一部分:动作(motion)也是造就伟大材料设计应用的重要部分。在材料设计中拥有大量诸如触摸涟漪效果和有意思的活动过渡效果等动作的同时,Design包引进了CoordinatorLayout,这个布局提供了对子视图之间触摸事件的更高层次的控件,也引进了一些Design包中许多构件充分利用的东西。
CoordinatorLayout和FloatingActionButton
两者使用的一个好例子是当你添加一个FloatingActionButton作为CoordinatorLayout的子元素,然后再将这个CoordinatorLayout传递给Snackbar.make()调用—这样的话,不是snackbar展示在FloatingActionButton的上面,而是在snackbar以动画的形式进入屏幕的进修FloatingActionButton充分利用了CoordinatorLayout提供的回调自动向上移动,然后在snackbar返回它的位置的时候,snackbar在Android 3.0以上的设备上产生动画退出屏幕,而不需要额外的代码。
CoordinatorLayout也提供了layout_anchor属性,该属性和layout_anchorGravity一起能够用于放置浮动视图,例如FloatingActionButton,并关联到其它视图。
CoordinatorLayout和App Bar
CoordinatorLayout的其它主要使用实例包括app bar(即先前的action bar)和滚动技术。你也许已经在布局中使用Toolbar了,Toolbar允许你轻易地自定义外观和应用中图标部分与布局的集成。Design包在这一点走得更远:使用AppBarLayout允许Toolbar和其它的视图(如TabLayout提供了tab)对标记了ScrollingViewBehavior的兄弟视图中的滚动事件产生反馈。由此,你可以像这样创建布局:
1 <android.support.design.widget.CoordinatorLayout 2 xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent"> 6 7 <! -- Your Scrollable View --> 8 <android.support.v7.widget.RecyclerView 9 android:layout_width="match_parent" 10 android:layout_height="match_parent" 11 app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 12 13 <android.support.design.widget.AppBarLayout 14 android:layout_width="match_parent" 15 android:layout_height="wrap_content"> 16 <android.support.v7.widget.Toolbar 17 ... 18 app:layout_scrollFlags="scroll|enterAlways"> 19 20 <android.support.design.widget.TabLayout 21 ... 22 app:layout_scrollFlags="scroll|enterAlways"> 23 </android.support.design.widget.AppBarLayout> 24 </android.support.design.widget.CoordinatorLayout>
现在,在用户使用RecyclerView的时候,AppBarLayout能够对通过使用子视图的滚动标签来控件他们如何滚进和滚出屏幕的事件进行响应。这些标签包括:
- scroll:这个标签应该是想要滚出屏幕的所有视图的集合—对于那些并不使用这个标签的视图,他们而被订在屏幕的顶部。
- enterAlways:这个标签确保任何向下的滑动都会使得这个视图可见,激活了“快速返回”模式。
- exitUntilCollapsed:这个标签使得视图不会滚动出来,除非在退出之前该视图变得“collapsed”(它的minHeight)。
注意一点:所有使用scroll标签的视图必须在不使用该标签的视图之前声明。这将确保所有的视图从顶部退出,而把固定的元素落下。
Collapsing Toolbar
把Toobar直接添加到AppBarLayout里面给予了你enterAlwayCollapsed和exitUntilCollapsed这些滚动标签的访问权限,而不是对不同元素如何对collapsing作出响应的详细控件能力。要想获取后者的效果,你可以使用CollapsingToolbarLayout:
1 <android.support.design.widget.AppBarLayout 2 android:layout_height="192dp" 3 android:layout_width="match_parent"> 4 <android.support.design.widget.CollapsingToolbarLayout 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 app:layout_scrollFlags="scroll|exitUntilCollapsed"> 8 <android.support.v7.widget.Toolbar 9 android:layout_height="?attr/actionBarSize" 10 android:layout_width="match_parent" 11 app:layout_collapseMode="pin"/> 12 </android.support.design.widget.CollapsingToolbarLayout> 13 </android.support.design.widget.AppBarLayout>
以上设置使用了CollapsingToolbarLayout的app:layout_collapseMode=”pin”属性以确保Toolbar本身在视图collapse的时候依然能够被订在屏幕顶部。而可能更多的情况是,在你一起使用CollapsingToolbarLayout和Toolbar的时候,当布局完全可见的时候,标题将自动显示得更大,然后在toolbar collapse的时候过渡到它的默认尺寸。请注意在这些情况下,你应该调用CollapsingToolbarLayot的setTittle(),而非Toolbar本身的setTitle()。
查看Collapsing Toolbar效果请点击(打不开时候注意翻墙)
除了可以订住一个视图之外,你能够使用app:layout_collapseMode=”parallax”(可选情况下,使用app:layout_collapseParallaxMultiplier=”0.7”来设置滚动视差乘法因子)来实现滚动视差效果(例如CollapsingToolbarLayout内部的兄弟ImageView)。这个使用示例将app:layout_collapseParallaxMultiplier和CollapsingToolbarLayout的app:contentScrim=”?attr/colorPrimary”配成对使用,结果是在视图collapse时,添加了全出血纱布效果。
CoordinatorLayout和自定义视图
要记住和重要一点是:CoordinatorLayout并没有任何对FloatingActionButton或AppBarLayout工作原理的天生理解,它仅仅以Coordinator.Behavior的形式提供了额外的API,而Coordinator.Behavior允许子视图更好地控制触摸事件和手势,但也声明了彼此之间的依赖性并通过onDependentViewChanged()方法接收到回调。
视图可以通过使用CoordinatorLayout.DefaultBehavior(YourView.Behavior.class)注解来声明一个默认的Behavior,或者在布局文件中通过app:layout_behavior=”com.example.app.YourView$Behavior”属性来设置。框架层使得对任意视图而言集成CoordinatorLayout成为可能。
注意,Design支持包依赖于V4支持包和AppCompat支持包,后两者将会在你导入Design支持包依赖时自动引入。我们也注意到这些新的控件在Android Studio Layout Editor’s Design
(在CustomView下面找到它们)视图中可以使用,给你提供了更容易的方式来预览一些新的构件。
Design支持包,AppCompat支持包和其它所有的Android支持包非常重要的工作,以提供所需的构建块来不一切必从头开始构建一个现代,美观的Android应用。