美文网首页Androidandroid基础support design
Material Design 之 Toolbar 开发实践总结

Material Design 之 Toolbar 开发实践总结

作者: 依然范特稀西 | 来源:发表于2016-12-06 19:21 被阅读9776次

    在2014年Google IO 大会上,Google 推出了一套全新的设计规范Material Design,这也为广大的Android 开发者带来了福音,不用像以前一样照着IOS 视觉稿来开发Android APP,Material Design 的视觉风格本身就比较炫酷。请看Material Design 中文版,而Google 也为我们提供符合Material Design 风格的一系列组件,这大大的提高了我们的开发效率。由于APP改版在做Material Design 化,所以后面会结合项目中的使用情况写几篇关于Material Design 组件的文章。第一篇就从 Toolbar开始吧。

    一、 认识Toolbar

    官方原话:A Toolbar is a generalization of action bars
    for use within application layouts. 意思就是 Toolbar 是应用内的action bars 的一个归纳。好像有点难懂,看不懂这句话没关系,我们只要知道,Toolbar 使用来替代原来的ActionBar 的就行了。我们来看一下Toolbar的类继承关系,如下图:

    toolbar_class.png

    从继承关系可以看出,继承的是ViewGroup,也就是说Toolbar 是一个ViewGroup 容器,知道了这一点对于后面的理解就比较容易了。那么接下来我们看一下这个容器里面有些什么东西,还是看一下官方文档:


    toolbar.png

    文档说得很清楚,一个Toolbar 从左到右包括了 一个navigation button、一个logo、一个title和subtitle、一个或多个自定义的View和一个 action menu 这5部分。也就是这个ViewGroup 容器里面包含了这五部分内容,对应着一个界面看一下:

    toolbar_5.1.png toolbar_5.png

    上面的图就是一个Toolbar 容器从左到右的五部分内容,当然了,我们要为它设置相应的内容才行(比如:设置了nacigation button才会显示,不设置是不会显示出来的),否则它就只是一个空的ViewGroup,好了,到此我们就了解了一个Toolbar 是什么样子的。那么下面我们看一下该怎么使用Toolbar。

    二、Toolbar 的使用

    首先看一下Toolbar 有哪些比较常用和重要的方法
    XML中的常用属性(注意开头是自定义命名空间 xmlns:toolbar="http://schemas.android.com/apk/res-auto", 而不是 android,如果使用android:navigationIcon这种事无效的,必须使用 toolbar:navigationIcon):

    • toolbar:navigationIcon 设置navigation button

    • toolbar:logo 设置logo 图标

    • toolbar:title 设置标题

    • toolbar:titleTextColor 设置标题文字颜色

    • toolbar:subtitle 设置副标题

    • toolbar:subtitleTextColor 设置副标题文字颜色

    • toolbar:popupTheme Reference to a theme that should be used to inflate popups shown by widgets in the toolbar.

    • toolbar:titleTextAppearance 设置title text 相关属性,如:字体,颜色,大小等等

    • toolbar:subtitleTextAppearance 设置subtitle text 相关属性,如:字体,颜色,大小等等

    • toolbar:logoDescription logo 描述

    • android:background Toolbar 背景

    • android:theme 主题

    以上就是Toolbar比较常用的 XML 中的属性,这些属性也可以在代码中设置,代码如下:

            //设置NavigationIcon
            toolbar.setNavigationIcon(R.drawable.ic_book_list);
            // 设置navigation button 点击事件
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finish();
                }
            });
            // 设置 toolbar 背景色
            toolbar.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
            // 设置 Title
            toolbar.setTitle(R.string.toolbar_title);
            //  设置Toolbar title文字颜色
            toolbar.setTitleTextColor(getResources().getColor(R.color.white));
            // 设置Toolbar subTitle
            toolbar.setSubtitle(R.string.sub_title);
    
            toolbar.setSubtitleTextColor(getResources().getColor(R.color.white));
            // 设置logo
            toolbar.setLogo(R.mipmap.ic_launcher);
            // 设置 NavigationIcon 点击事件
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finish();
                }
            });
            //设置 Toolbar menu
            toolbar.inflateMenu(R.menu.setting_menu);
            // 设置溢出菜单的图标
            toolbar.setOverflowIcon(getResources().getDrawable(R.drawable.abc_ic_menu_moreoverflow_mtrl_alpha));
            // 设置menu item 点击事件
            toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    switch (item.getItemId()){
                        case R.id.item_setting:
                            //点击设置
                            break;
                    }
                    return false;
                }
            });
    

    ** 以下步骤说明如何为一个Activity 添加 Toolbar**
    1, 在gradle 中添加 v7 appcompat 支持库

    compile 'com.android.support:appcompat-v7:24.2.1'
    

    2,确保你的Activity 是继承的AppCompatActivity

    public class ToolbarActivity extends AppCompatActivity{
     //...
    }
    

    3,在应用清单中,将 <application> 元素设置为使用 appcompat 的其中一个 NoActionBar主题。使用这些主题中的一个可以防止应用使用原生 ActionBar类提供应用栏。例如:

    <application    android:theme="@style/Theme.AppCompat.Light.NoActionBar"    />
    

    当然了,也可以不在application 节点,也可以在<activity> 节点设置主题,如果每个activity 都是一样的主题,可以设置在application。主题选择任意一个 appCompat NoActionBar 主题或则他们的子主题(比如自定义的主题,parent为appCompat 的 NoActionBar)

    4,在 Activity 的布局文件中添加toolbar

     <android.support.v7.widget.Toolbar
          android:id="@+id/tool_bar_2"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:background="@color/colorPrimary"
          toolbar:navigationIcon="@drawable/ic_book_list"
          toolbar:title="@string/toolbar_title"
          toolbar:titleTextColor="@color/white"
          toolbar:theme="@style/ToolbarTheme"
          toolbar:popupTheme="@style/ThemeOverlay.AppCompat.Light"
          >
      </android.support.v7.widget.Toolbar>
    

    5,在Activity 中对 Toolbar 做一些相关的操作,如:设置标题,设置navigation button 点击事件,添加溢出菜单

     private void initToolbar(){
           Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar_2);
           toolbar.setNavigationOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View v) {
                   finish();
               }
           });
           //添加溢出菜单
           toolbar.inflateMenu(R.menu.setting_menu);
           // 添加菜单点击事件
           toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
               @Override
               public boolean onMenuItemClick(MenuItem item) {
                   switch (item.getItemId()){
                       case R.id.item_setting:
                           //点击设置菜单
                           break;
                   }
                   return false;
               }
           }); 
    
        }
    

    6,溢出菜单文件如下:

    <?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/item_collect"
               android:icon="@drawable/ic_favorite_more"
               android:title="收藏"
               app:showAsAction="ifRoom"
            />
    
       <item android:id="@+id/item_setting"
             android:title="设置选项"
             app:showAsAction="never"
             />
        <item android:id="@+id/item_model"
              android:title="夜间模式"
              app:showAsAction="never"
            />
    </menu>
    

    注意 app:showAsAction ,这个属性是设置菜单该怎么显示,取值有5种,主要应用的有ifRoom、never、always 这三种, ifRoom 表示 如果Toolbar 上有显示空间就显示在Toolbar 上,如果没有空间就展示在溢出菜单里,never 表是总是显示在溢出菜单里,always 表示总是显示在Toolbar 上。效果如下:

    toolbar_menu1.png

    点击溢出菜单如下:


    toolbar_menu2.png

    ** 以上就是 Toolbar 的基本使用**

    三、项目中对Toolbar 的一些特殊需求

    上面讲了Toolbar 的基本使用方法,但是在实际的项目中可能这些还不够,比如设计师觉得默认菜单文字颜色不好,要换菜单文字的颜色。或者溢出菜单文字的大小不好,要换文字的大小。或者需要在Toolbar 上添加自定义View等等。下面就讲一下项目中遇到的几个特殊需求。PS:我个人觉得Google 默认的文字字的颜色大小等等都是比较合适的,一般情况下不要去更改。但是有时候身不由己,产品、设计说了算。我们也就只有改了(无奈脸...)。

    1,更改溢出菜单文字的颜色和文字的大小
    默认情况下,弹出的溢出菜单的文字的颜色是黑色的,如下:

    toolbar_menu2.png

    要更改溢出菜单文字的颜色,我们只需要为Toolbar 添加一个主题,在styles.xml 文件中添加一个主题:

     <style name="ToolbarTheme" parent="Theme.AppCompat.Light">
            <!-- 设置 toolbar 溢出菜单的文字的颜色 -->
          <item name="android:textColor">@android:color/holo_red_dark</item> 
        </style>
    

    效果如下:

    overmenu1.png

    看到其他的一些技术文章说的改变溢出菜单的文字颜色添加actionMenuTextColor 属性,其实不是的,这个属性是控制显示在Toolbar 上的菜单的文字颜色,后面会说到。
    改变溢出菜单文字的大小,在style 中添加如下代码:

      <!-- 设置toolbar 溢出菜单的字体大小-->
      <item name="android:textSize">25sp</item>
    

    效果如下:

    overmenu2.png

    2,** 更改显示在Toolbar 上的菜单文字颜色**
    更改显示在Toolbar 上菜单文字的颜色才是用上提到的那个属性actionMenuTextColor,注意,不要搞混淆了。显示在Toobar上的菜单默认文字是黑色的,如下图:

    toolbar_menu12.png

    如上图所示:显示在Toolbar 上的 发布 菜单,默认显示是黑色,设计师肯定不干了,要你更改颜色。在 style 中添加如下代码:

     <!-- 设置 显示在toobar上菜单文字的颜色 -->
     <item name="actionMenuTextColor">@android:color/white</item>
    

    特别注意,前面是没有android: 前缀的 ,有android: 前缀是没有效果的。最后,更改颜色后如下图:

    toolbar_menu13.png

    ** 顺便提一下,改变显示在Toolbar 上的菜单的文字大小和改变溢出菜单文字大小的方法一样,都是android:textSize 这个属性。**

    最后,贴出Toolbar 主题的全部代码:

     <style name="ToolbarTheme" parent="Theme.AppCompat.Light">
            <!-- 更换Toolbar OVerFlow menu icon -->
          <item name="actionOverflowButtonStyle">@style/OverFlowIcon</item>
            <!-- 设置 toolbar 溢出菜单的文字的颜色 -->
          <item name="android:textColor">@android:color/holo_red_dark</item>
            <!-- 设置 显示在toobar上菜单文字的颜色 -->
          <item name="actionMenuTextColor">@android:color/white</item>
            <!-- 设置toolbar 弹出菜单的字体大小和溢出菜单文字大小-->
          <item name="android:textSize">15sp</item>
        </style>
    
        <style name="OverFlowIcon" parent="Widget.AppCompat.ActionButton.Overflow">
            <item name="android:src">@drawable/abc_ic_menu_moreoverflow_mtrl_alpha</item>
        </style>
    

    最后,别忘了在Toolbar 的xml 文件中应用主题:

     <android.support.v7.widget.Toolbar
          android:id="@+id/tool_bar"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:background="@color/colorPrimary"
          toolbar:navigationIcon="@mipmap/navigation_back_white"
          toolbar:title="@string/toolbar_title"
          toolbar:titleTextColor="@color/white"
          android:theme="@style/ToolbarTheme"
          >
    
      </android.support.v7.widget.Toolbar>
    

    3,** 在Toolbar 上添加 自定义View **
    这种需求很常见,如:很多 APP 里都有搜索功能,在Toolbar 上添加一个搜索框,如网易云音乐的搜索界面:

    toolbar_search.png

    像上面的搜索 Toolbar 也很简单,前文已经提到过,在Toolbar 中添加View就可以了,代码如下:

    <android.support.v7.widget.Toolbar
          android:id="@+id/tool_bar_4"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:background="@color/colorPrimary"
          android:visibility="gone"
          toolbar:navigationIcon="@mipmap/navigation_back_white"
          toolbar:theme="@style/ToolbarTheme"
          >
          <!-- ToolBar 中添加一个 编辑框 -->
          <EditText
              android:id="@+id/edit_search"
              android:layout_width="match_parent"
              android:layout_height="match_parent"/>
      </android.support.v7.widget.Toolbar>
    

    然后,在代码中得到这个编辑框的内容:

      private void initToolbar(){
            mToolbar3 = (Toolbar) findViewById(R.id.tool_bar_4);
            mToolbar3.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finish();
                }
            });
            mToolbar3.inflateMenu(R.menu.menu_search);
            
            mToolbar3.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    if(item.getItemId() == R.id.item_search){
                        // do search 
                    }
                    return false;
                }
            });
            // 获取ToolBar 上的编辑框
            EditText searchEdit = (EditText) mToolbar3.findViewById(R.id.edit_search);
            // 获取内容
            String content = searchEdit.getText().toString();
        }
    

    效果如下:

    toolbar_search2.png

    很容易就可以做出一个搜索界面,以上只是举例,Toolbar 中添加自定义View的场景还是很多的,只要知道是在Toolbar 里面添加View ,不管什么样的需求都没什么困难的。

    ** Demo 源码请看GithubMaterialDesignSamples**

    ** 好了,以上就是 Toolbar 在项目中的使用和总结,水平有限,难免会有错误,如有什么问题,欢迎留言大家一起探讨。**

    相关文章

      网友评论

      • 稻草僧:很详细
      • 6e6a4aa63ebb:<style name="ToolbarTheme" parent="Theme.AppCompat.Light">
        <!-- 设置 toolbar 溢出菜单的文字的颜色 -->
        <item name="android:textColor">@android:color/holo_red_dark</item>
        </style>

        这是设置整个app的字体颜色吧??
        木溪bo:文章貌似是说将toolbar的主题设置位置为toolbartheme
      • 沐小晨曦:对不起,我来晚了。但是,还是要说一句,牛批!
      • eaaf3d89035a:感谢分享!楼主大佬辛苦了:+1: :+1:
        麦香菌:我也在toolbar里加了个textview做title,但有右边的menu顶着textview好像就不能居中了。
      • 649d89c36d8a:toolbar title 可以居中么
        依然范特稀西:@卢诗如 怎么会不行呢,就按照文中的方法
        649d89c36d8a:我加了好像不行呐
        依然范特稀西:@卢诗如 可以添加自定义View
      • 梦华芳秋:在 toolbar.inflateMenu(R.menu.tool_bar_setting);设置右侧的menu时,记得一定不要有getDelegate().setSupportActionBar(toolbar);否则无效!:grin:
      • 飘渺云轩:请问一下,为啥设置setSupportActionBar(toolbar);后NavigationIcon的点击事件无响应了呢
        飘渺云轩:@JayZhouFan 检查无数遍了,还是这个情况
        依然范特稀西:@飘渺云轩 没有碰到过啊,你再仔细检查一下代码呢
      • 上官步凡:太棒了,写的!!!
      • Ja_Nein:没说怎么让溢出菜单图标设置成文字啊 :joy:
        依然范特稀西:@Ja_Nein 将你要显示的menu 的showAsAction 设置成always,不要设置icon ,就可以在toolbar s上显示文字菜单了
      • fight2048:请问如何让toolbar只显示文字菜单或者图标+文字的菜单呢?
        fight2048:@JayZhouFan 不好意思哈,我已经弄清楚了,谢谢你的回复哈。
        依然范特稀西:@江湖人称某二代 是要显示在Toolbar 上?还是溢出菜单?
      • 813a41643f67:很好,收藏了。
      • Freerain:很给力 把toolbar的知识点都讲到了 楼主辛苦啦
        依然范特稀西:@Freerain 共勉:smile:

      本文标题:Material Design 之 Toolbar 开发实践总结

      本文链接:https://www.haomeiwen.com/subject/mldlmttx.html