Android设计模式与最佳实践
上QQ阅读APP看书,第一时间看更新

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代码在运行时操作工具栏。

旧操作栏的改变使工具栏成为了一个更简单、更直观的放置全局操作的视图。然而,空间有限,对于更复杂的图形化导航组件,可以使用滑动式抽屉。