第二行代码学习笔记——第十二章:最佳的 UI 体验——Material Design 实战

本章要点

Android为了统一界面风格,在2014年的 Google I/O 大会上推出了一套全新的界面设计语言——Material Design。


12.1 什么是Material Design

Material Design 是由Google的设计工程师们基于传统优秀的设计原则,给丰富的创意和科学技术所发明的一套全新的界面设计语言,包含了视觉,运动,互动效果等特性。

它的出现,使Android的UI界面首次超过了iOS。

为了解决面向开发者的问题,比如:很多我们的开发者不知道什么样的界面和效果叫Material Design。就算搞清楚了,实现起来也是比较困难的,于是 Google I/O 大会上推出了 Design Support 库,这个库将 Material Design 中最具有代表性的一些控件和效果进行了封装,使得我们开发者能够轻松的将自己的应用程序 Material 化。

接下来我们学习 Design Support 这个库,并且配合其他组件来完成一个优秀的Material Design 应用。

新建一个 MaterialTest 项目。


12.2 ToolBar

ToolBar是我们接触的第一个 Material Design 控件,对于它的另一个相关控件ActionBar。

ActionBar的设计被限定只能位于活动的顶部,从而不能实现 Material Design 的效果。因此官方更加推荐使用ToolBar。

ToolBar的强大之处在于,它不仅继承了ActionBar的所有功能,而且灵活性很高。

任何一个新建项目,默认都会显示ActionBar。它是根据项目中指定的主题来显示的,打开AndroidManifest.xml文件,如下:

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        ...
    </application>

使用android:theme属性指定了一个AppTheme的主题。打开res/values/styles.xml文件,如下:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

这里定义了一个叫AppTheme的主题,然后指定了它的parent主题是Theme.AppCompat.Light.DarkActionBar。这个DarkActionBar是一个深色的主题,项目中自带的ActionBar就是因为指定了这个主题才出现的。

接下来我们使用ToolBar来代替ActionBar,通常Theme.AppCompat.NoActionBar(表示深色主题,将界面的主题颜色设成深色,陪衬颜色设成淡色)和Theme.AppCompat.Light.NoActionBar(表示淡色主题,将界面的主题颜色设成淡色,陪衬颜色设成深色)两种主题可选。那我们就选用淡色主题,如下所示:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

在AppTheme中重写了colorPrimary,colorPrimaryDark和colorAccent这3个属性的颜色。

现在我们已经将ActionBar隐藏起来了,使用ToolBar来代替ActionBar。修改activity_main.xml中的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

</FrameLayout>

使用了 xmlns:app 指定了一个新的命名空间。是由于 Material Design 是在 Android5.0 系统中才出现的,为了兼容之前老的系统,我们就必须使用app:attribute。

定义了一个Toolbar控件,它是有appcompat-v7库提供的。为了让ToolBar单独使用深色主题,这里我们使用 android:theme 属性,将Toolbar的主题指定成了ThemeOverlay.AppCompat.Dark.ActionBar。为了使Toolbar中的菜单按钮弹出的菜单项也变成淡色的主题,这里使用了 app:popupTheme ,是因为popupTheme这个属性是 Android5.0 新增的,这样我们就可以兼容 Android5.0 以下的系统了。

接下来我们修改MainActivity中的代码如下:

public class MainActivity extends AppCompatActivity {
   

    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar); //将Toolbar的实例传入
    }
}

这样我们就让它的外观和功能都和ActionBar一致了。运行程序如下:

toolbar

Toolbar常用的一些功能,比如修改标题栏上显示的文字内容。在AndroidManifest.xml中指定,如下:

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="Fruits">
            ...
        </activity>
    </application>

这里在activity新增了一个label属性,用于指定Toolbar显示的文字内容,如果没有指定就会默认使用application中指定的label内容,也就是我们的应用的名称。

为了丰富我们Toolbar,可以再添加 action 按钮。准备一些图片来作为按钮的图标。将它们放在 drawable-xxhdpi 目录下。创建一个 meum 文件夹。再创建一个toolbar.xml 文件,并编写代码如下:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/backup"
        android:icon="@drawable/ic_backup"
        android:title="BackUp"
        app:showAsAction="always" />

    <item
        android:id="@+id/delete"
        android:icon="@drawable/ic_delete"
        android:title="Detele"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/settings"
        android:icon="@drawable/ic_settings"
        android:title="Settings"
        app:showAsAction="never" />

</menu>

通过< item>标签定义 action 按钮,android:id 用于指定按钮的 id,android:icon 用于指定按钮的图标,android:title 指定按钮的文字。app:showAsAction 指定按钮显示的位置,使用app命名空间,为了能够兼容更低的系统。可选值:always(永远显示在Toolbar中,屏幕空间不足则不显示),ifRoom(屏幕空间足够的情况下显示在Toolbar中,不够则显示在菜单当中),never(永远显示在菜单中)。注意:Toolbar中的action按钮只会显示图标,菜单中的 action 只会显示文字。

修改MainActivity中的代码如下:

public class MainActivity extends AppCompatActivity {
   
     ...

    /**
     * 加载toolbar.xml文件
     *
     * @param menu
     * @return
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar, menu);
        return true;
    }

    /**
     * 处理各个按钮的点击事件
     *
     * @param item
     * @return
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.backup:
                Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show();
                break;
            case R.id.delete:
                Toast.makeText(this, "You clicked Delete", Toast.LENGTH_SHORT).show();
                break;
            case R.id.settings:
                Toast.makeText(this, "You clicked Settings", Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
        }
        return true;
    }
}

重新运行程序,效果如下:

menutoolbar

这些 action 按钮都是可以响应点击事件的。

Toolbar的功能还远远不足这些,后面我们会结合其他控件来挖掘Toolbar的更多功能。


12.3 滑动菜单

滑动菜单是 Material Design 中最常见的效果之一。

12.3.1 DrawerLayout

滑动就是将菜单选项隐藏起来,通过滑动来将菜单显示出来。

Google提供了一个DrawerLayout控件,实现滑动菜单简单又方便。

DrawerLayout的用法:它是一个布局,在布局中放入两个直接子控件,第一个子控件是显示在主屏幕中的显示内容,第二个控件是滑动菜单中显示的内容。修改activity_main.xml中的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    </FrameLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#FFF"
        android:text="This is Menu"
        android:textSize="30sp" />


</android.support.v4.widget.DrawerLayout>

这个DrawerLayout是由 support-v4 库提供的。 我们可以看到第一个子控件FrameLayout(用于作为主屏幕显示的内容);第二个子控件TextView(作为滑动菜单中显示的内容),这个子控件中 android:layout_gravity 这个属性必须指定(滑动菜单是在屏幕的左边还是右边,left,right,这里我指定了start,根据系统语言进行判断,比如英语,汉语,滑动就在左边,阿拉伯语滑动就在右边)。

运行程序,左侧向右侧滑动,如图:

ch

向左滑动,或者点击菜单以外的区域,都可以将滑动菜单关闭。

为了解决用户不知道这个功能,Material Design建议我们在Toolbar 的最左边接入了一个导航按钮,点击也会将滑动菜单展示出来。(这样就相当于给用户提供了良两种打开滑动菜单的方式)。

将准备好的c_menu.png放在drawable-xxhdpi目录下,修改MainActivity中的代码如下:

public class MainActivity extends AppCompatActivity {
   

    private Toolbar toolbar;
    private DrawerLayout mDrawerLayout;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        mDrawerLayout= (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true); //显示导航按钮
            actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);//设置导航按钮图标(默认返回箭头,含义返回上一个活动)
        }
    }
    ...
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case an
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值