Toolbar的正确使用姿势

前言

Toolbar是谷歌在2014年Google IO 大会上推出的一套全新的设计规范Material Design。它的出现规范了Android开发者APP标题栏的设计风格,极大地提高了开发效率,而且Material Design设计规范也越来越多出现在我们常用的APP中。所以,学习和使用Toolbar是必要的。

初识Toolbar

先上一张图


谷歌官方对Toolbar的介绍

根据图中的资料,可以知道,Toolbar首先是一个ViewGroup,它是用来做APP的标题栏,其中包括5个部分,分别是一个导航按钮(a navigation button)、一个logo图片(a branded logo image)、一个标题和副标题(a title and subtitle)、一个或多个自定义View(one or more custom views)以及一个action menu( an action menu)。看一张效果图
具体效果图

从效果图中,我们可以很明显地看出来5个部分都是哪里,因为Toolbar是一个ViewGroup,你只有都设置出来了才会显示,如果不设置的话,那么都是空的,啥也没有。那么究竟应该怎么设置呢?下面我们就开始使用Toolbar。

Toolbar的正确使用姿势

第一步 导入v7包

implementation 'com.android.support:appcompat-v7:27.0.2

第二步 继承AppCompatActivity

public class MainActivity extends AppCompatActivity

第三步 设置主题theme

 <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.NoActionBar">

这里如果不想让所有的app共用一个主题,可以不在application中设置,可以在单独的activity里面设置。

第四步 各种设置

前三步都很简单,而且基本都是新建项目都能创建好的,这里就不多讲了,重点就在这第四步怎么设置这里了。
首先,在布局文件中的基本属性设置:

 <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        app:logo="@mipmap/ic_launcher"
        app:title="标题"
        app:titleTextColor="#fff"
        app:subtitle="副标题"
        app:subtitleTextColor="#fff"
        app:navigationIcon="@drawable/ic_menu"
        android:theme="@style/Base.Theme.AppCompat.Light"
        app:popupTheme="@style/toolBar_pop_item"
        >

这里的属性设置了导航按钮、logo和主标题副标题,属性名称很清楚不多讲,action menu的设置需要通过代码,自定义View放到后面来讲。
导航Button设置点击事件

 mToolbar=findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);//利用Toolbar代替ActionBar
        //设置导航Button点击事件
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this,"点击导航栏",Toast.LENGTH_SHORT).show();
            }
        });

设置action menu

 //设置移除图片  如果不设置会默认使用系统灰色的图标
        mToolbar.setOverflowIcon(getResources().getDrawable(R.drawable.icon_action));
//填充menu
        mToolbar.inflateMenu(R.menu.toolbar_menu);
//设置点击事件
        mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()){
                    case R.id.action_settings:
                        Toast.makeText(MainActivity.this,"action_settings",Toast.LENGTH_SHORT).show();

                        break;
                    case R.id.action_share:
                        Toast.makeText(MainActivity.this,"action_share",Toast.LENGTH_SHORT).show();

                        break;
                    case R.id.action_search:
                        Toast.makeText(MainActivity.this,"action_search",Toast.LENGTH_SHORT).show();

                        break;
                        default:
                            break;
                }
                return false;
            }
        });

你发现设置了这一对之后,action menu 依然没有显示出来,因为你还没有重写onCreateOptionsMenu,让action menu显示出来。

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar_menu,menu);
        return true;
    }

加上这个重写方法以后,action menu就会显示,如同上面的介绍图一样,这个时候有朋友就可能问了,为啥action menu在标题栏上显示这么多图标


action menu

下面我们来看一下R.menu.toolbar_menu这个配置文件

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:title="测试1"
        android:icon="@drawable/icon_search"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/action_share"
        android:orderInCategory="100"
        android:title="测试2"
        android:icon="@drawable/icon_notify"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/action_search"
        android:orderInCategory="100"
        android:title="设置"
        app:showAsAction="never"/>
    <item
        android:id="@+id/action_search2"
        android:orderInCategory="100"
        android:title="关于"
        app:showAsAction="never"/>
</menu>

这其中app:showAsAction属性的作用是来控制item在标题栏上展示的形式,一般多取三个值:always、ifRoom以及never。always:总是展示在标题栏上;ifRoom如果标题栏上有位置就展示出来;never:永不展示标题栏。我这里设置的是前两个item的showAsAction属性是ifRoom,后两个是never,所以在状态栏上前两个图标被展示出来了,因为还有两个item未被在标题栏上显示出来,系统会默认一个图标让用户来点击。这里如果我们把mToolbar.setOverflowIcon(getResources().getDrawable(R.drawable.icon_action)); 这句代码注释掉,结果就会是这样
系统默认的图标

,如果没有未被展示的item,这里就不会出现这个图标。

点击溢出图标,系统默认的弹出样式是这样的
系统默认弹出样式

没错,就是这么丑,那么怎么设置一下这个弹出框,能让它变得好看一些,并且符合我们设计师的要求呢?在xml文件里
设置弹出框的属性

就是通过app:popupTheme属性来控制的,在style文件里可以设置风格、字体颜色大小等等属性。简单看一下toolBar_pop_item

<style name="toolBar_pop_item" parent="Base.Theme.AppCompat.Light">
        <item name="android:textColor">@color/colorAccent</item>
</style>

看一下现在的效果
设置style之后的效果

具体的效果根据UI设计师的设计手稿来定

小结

关于ToolBar的使用,在xml布局文件里面,可以通过属性设置好导航Button、logo图标以及正副标题,在代码可以设置导航Button的点击事件,action menu通过代码来设置,如果要显示出来记得重写onCreateOptionsMenu(Menu menu)方法,关于让menu里面的item在标题栏中的显示通过showAsAction属性来控制,常用的三个属性分别是always、ifRoom以及never,item弹出的样式可以通过style文件来设置。知道这些,基本就可以完成标题栏导航栏、logo图标、正副标题已经action menu的设置了,关于自定义View,下面会单独拿出来讲。

标题居中问题和自定义Toolbar

关于标题居中问题,我看很多小伙伴们都提出过,其实解决起来非常的简单,就是利用自定义View。之前文中提到过Toolbar是一个ViewGroup,如果需要添加自定义View,只需要在Toolbar里面增加其子ViewGroup或者子View。

<android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:gravity="center_vertical"

            >
            <ImageView
                android:id="@+id/iv_back"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_back"
                android:layout_centerVertical="true"
                />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#fff"
                android:text="标题"
                android:textSize="18sp"
                android:layout_centerHorizontal="true"
                />

               <EditText
                   android:visibility="gone"
                   android:layout_width="match_parent"
                   android:layout_height="wrap_content"
                   android:layout_marginLeft="50dp"
                   android:layout_marginRight="50dp"
                   android:layout_centerHorizontal="true"
                   android:background="@drawable/search_bg"
                   android:drawableLeft="@drawable/icon_search"
                   android:padding="5dp"
                   android:textColorHint="#fff"
                   android:hint="请输入搜索内容"
                   android:gravity="center"
                   android:cursorVisible="false"
                   />
        </RelativeLayout>
    </android.support.v7.widget.Toolbar>

通过这种自定义View方式就可以解决标题居中的问题,看一下效果
标题居中效果

注意这里返回键不要通过Toolbar的导航Button设置,这样会影响标题居中的效果,直接在自定义View里面设置就行了。
有些App用搜索框,其实也是利用自定义View来实现,实现起来也很简单,搜索框在中间跟标题重叠,通过设置可见性来调控,简单看一下效果


搜索标题栏

写到这里,肯定会有小伙伴问了,这里使用Toolbar有什么用,我自己写一个RelativeLayout或者其他什么布局都能实现,为啥非要用Toolbar呢?这里说一下,使用Toolbar比起传统的自定义布局的好处。第一、不需要考虑标题栏和系统状态栏匹配的问题,你自己写还得匹配系统状态栏;第二、就是Toolbar可以和其他的MD设计风格的空间连用,做出比较炫的效果,比如Toolbar+NestScrollView,Toolbar+DrawerLayout + NavigationView等等;第三、谷歌推荐的控件当然要用(嘿嘿,强行凑三条)。

总结

Toolbar是一个ViewGroup,用来做App的标题栏,主要有5部分,导航Button、logo、正副标题、自定义View以及action menu。通过xml文件属性可以设置导航Button、logo和正副标题,通过代码设置action menu,利用自定义View可以解决标题不居中的问题。

最后的最后,放上文中demo的地址:https://github.com/kaka10xiaobang/ToolbarDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容

  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,209评论 0 17
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 本文出自 “阿敏其人” 简书博客,转载或引用请注明出处。 一、Google口中的ToolBar 从Toolbar说...
    阿敏其人阅读 4,143评论 2 36
  • 这世界多少人,我却唯独对你说了喜欢你 你知道 ,这句话要多大勇气吗? 我辜负了那么多对我好的人,选择了对我不好的人...
    赴里阅读 500评论 0 0
  • 人活一世, 富贵算什么,人品才值钱。 百年之后,尘归尘土归土, 一切都会烟消云散。 黄金万两,你也带不走; 钞票一...
    JoanXu阅读 280评论 0 1