
3.1 应用程序栏
Android应用程序在屏幕顶部总是有一个工具栏,该区域称作操作栏,通常用于显示标题和顶级菜单。自Android 5(API 21)Material Design开始,可以用更灵活的应用程序栏来替代操作栏。应用程序栏允许设置颜色,可以放置在屏幕上的任意位置,并且比操作栏包含更多的内容。
大多数Android Studio模板使用的主题默认包含旧的操作栏,首先我们需要做的是删除旧版本。要学习如何删除旧的操作栏并将其替换为自定义应用程序栏,请按以下步骤操作。
(1)新建一个Android项目,使用空活动(empty activity)模板,并使用主题编辑器设置Material主题。
(2)打开styles.xml文件,像下面这样编辑style定义:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
(3)在activity_main.xml旁创建一个叫作toolbar.xml的XML文件。
(4)编辑该XML文件,内容如下所示:
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="? attr/actionBarSize" android:background="? attr/colorPrimary" android:theme="@android:style/Theme.Material" android:translationZ="4dp" />
(5)在activity_main.xml文件中添加以下元素。
<include android:id="@+id/toolbar" layout="@layout/toolbar" />
(6)最后,编辑dimens.xml文件中的margin值:
<resources> <dimen name="activity_horizontal_margin">0dp</dimen> <dimen name="activity_vertical_margin">0dp</dimen> </resources>
此工具栏和其他ViewGroup一样,都位于根布局中。因此,它不会像旧的操作栏那样与屏幕边缘齐平,这就是需要调整布局margin的原因。稍后会用到CoordinatorLayout,它会自动实现大部分内容。但目前,了解工具栏的工作原理非常有用。
工具栏现在的位置和阴影与原来的一样,但是没有任何内容或功能。可以通过编辑Java部分中活动的onCreate()完成替换,如下所示:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); if (toolbar ! = null) { setSupportActionBar(toolbar); } }
此处可能会产生一个报错,因为有两个可以导入的库。按Alt+Enter并选择Toolbar的支持版本,如图3-1所示。

图3-1
当编写Java代码时,为了节省时间,可以修改设置,自动导入代码中包含的Java库。在File | Settings(文件|设置)菜单下,选择Editor | General | Auto Import(编辑器|常规|自动导入),即可实现自动导入。
当在API 20或者更低版本的模拟器上测试项目时,很容易发现AppCompat主题的一个缺点——虽然使用colorPrimaryDark为状态栏声明了一种颜色,但状态栏仍是黑色的,如图3-2所示。API 21及其更高版本不存在这个问题。

图3-2
不过,考虑到现在可延伸的用户人数,上述问题以及缺乏自然阴影问题的代价很小。
现在已用工具栏替换了老式的操作栏,并将其设置为应用程序栏(有时称为主工具栏)。下面将更深入地了解它的工作方式,以及如何通过Asset Studio选择符合Material的动作图标。
3.1.1 图像资源
应用程序栏可以包含文本菜单,但是由于空间有限,使用图标更为常见。Android Studio通过其Asset Studio提供了一组可用的Material图标。要使用这些图标,请遵循以下步骤。
(1)在项目资源管理器中,从drawable文件夹的菜单中,选择New |Image Asset(新建|Image Asset)。
(2)然后选择Action Bar and Tab Icons(操作栏和选项卡图标)作为Asset Type(资源类型),单击Clipart(剪贴画图标),从剪贴画集合中选择一个图标,如图3-3所示。

图3-3
(3)此图标一定是修整过的,内边距是0%。
(4)根据工具栏背景颜色是浅色还是深色选择主题。
(5)提供合适的名称,然后单击Next(下一步),如图3-4所示。

图3-4
更大的Material图标集合可以从Google的Material Design网站Icons页面下载。
Asset Studio可以自动生成4种屏幕密度的图标,并将它们放置在正确的文件夹中,以便将它们部署在适当的设备上。它甚至还应用了Material Design中图标所需的54%不透明黑色。为了将图标加到应用程序栏中,需要在相应的菜单项中添加一个图标属性。稍后,导航抽屉将提供顶级功能访问。但要了解如何使用应用程序栏,需要添加一个搜索功能。为此功能所选择的图标,称作ic_action_search。
3.1.2 使用动作
动作图标保存在drawable文件夹中,通过在菜单XML文件中添加菜单项,可以将动作图标添加到操作栏中。根据首次创建项目时使用的模板,可能需要添加一个新目录res/menu和一个名为main.xml或mena_main.xml的文件。无论使用什么文件名,只要是通过New | Menu resource file(新建|菜单资源文件)创建的文件就可以。可以按如下所示添加动作:
<menu 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" tools:context="com.example.kyle.appbar.MainActivity"> <item android:id="@+id/action_settings" android:orderInCategory="100" android:title="@string/app_name" app:showAsAction="collapseActionView" /> <item android:id="@+id/action_search" android:icon="@drawable/ic_action" android:orderInCategory="100" android:title="@string/menu_search" app:showAsAction="ifRoom" /> </menu>
请注意,前面的示例使用了对字符串资源的引用,因此必须在strings.xml文件中附加一个定义,如下所示:
<string name="menu_search">Search</string>
菜单项会自动添加到应用程序栏中,标题取自字符串文件中string name="app_name"的定义。当以这种方式构造时,组件的位置是依据Material指南确定的。
要查看实际运行情况,请执行以下步骤。
(1)打开Java代码中的主活动并添加字段:
private Toolbar toolbar;
(2)然后,在onCreate()方法中添加以下代码:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); if (toolbar ! = null) { setSupportActionBar(toolbar); } toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.setTitle("A toolbar"); toolbar.setSubtitle("with a subtitle");
(3)最后,将以下方法添加到活动中:
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu_main, menu); return true; }
现在,应该能在设备或模拟器上看到新的工具栏了,如图3-5所示。

图3-5
可以在工具栏中添加任何想要的视图,使工具栏比旧的操作栏更加实用。工具栏中可以同时包含多个视图,通过使用布局的gravity属性可以将它们放置在任意位置上。正如之前看到的标题和副标题,工具栏拥有自己特定的方法。我们也可以用这些方法添加图标和logo。但在这样做之前,最好先根据Material Design指南探索应用程序栏的最佳实践。
3.1.3 应用程序栏结构
虽然这里使用的技术符合Material指南(除了确保其高度外,无须做太多的工作),但有些时候也会使用自定义的工具栏布局替换操作栏。此时,需要知道的是如何对组件进行空间和位置的调整。这些对于平板计算机和台式机来说,略有不同。
1.手机
对于应用程序栏,只需记住几个简单的结构规则即可。这些规则涵盖外边距(margin)、内边距(padding)、宽度(width)、高度(height)和位置(positioning)。它们在不同平台、屏幕方向上不同。
❑ 纵向模式下应用程序栏的layout_height为56dp,横向为48dp。
❑ 应用程序栏填充满屏幕宽度或是宽度等同内部列宽,二者择其一。layout_width有match_parent的属性值。
❑ 应用程序栏的elevation比它控制的Material表单的elevation要大2dp。
❑ 上述规则的例外情况是,如果一个卡片或对话框有自己的工具栏,那么两者可以共享相同的elevation。
❑ 应用程序栏的padding精确为16dp,这意味着内部的图标不能有自己的padding或margin,图标边距与此边界共享,如图3-6所示。

图3-6
❑ 标题文本的颜色取自主题的主文本颜色,图标的颜色取自次文本颜色。
❑ 标题应该位于距工具栏左侧72dp、底部20dp处。即使扩展工具栏,此规则也适用,如图3-7所示。

图3-7
❑ 标题的文字大小设置为android:textAppearance="? android:attr/textAppear-anceLarge"。
2.平板计算机
在为平板计算机和台式机构建应用程序栏时,规则是相同的,但以下情况除外。
❑ 工具栏高度始终为64dp。
❑ 标题缩进80dp,且在栏扩展时不会向下移动。
❑ 应用程序栏的padding是24dp,顶部除外,顶部是20dp。
根据Material指南,我们已成功地构建了一个应用程序栏。动作图标如果不执行某个动作,就没有任何用处。本质上讲,当应用程序栏假定操作栏功能时,它实际上只是一个指向菜单的入口。我们稍后将返回学习菜单和对话框,但现在需要快速了解如何使用Java代码在运行时操作工具栏。
旧操作栏的改变使工具栏成为了一个更简单、更直观的放置全局操作的视图。然而,空间有限,对于更复杂的图形化导航组件,可以使用滑动式抽屉。