Toolbar 的使用

0. 写在前面

Android 新人,博文是我的学习笔记,用于加深理解和记忆。这篇文章是我的第一篇文章,难免有错漏之处,或者不严谨的地方。有问题和意见,欢迎提出。

1. 基本使用

1.1 xml

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    app:title="Title" />

1.2 Java

与普通控件差别不大,方法很多,这里不再赘述,具体可看 Android Studio 的补全提醒

2. Toolbar 上的 menu

2.1 先在 menu 文件夹中新建一个 tool_bar_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/andro
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/search_btn"
        android:icon="@drawable/ic_search_white_24dp"
        android:title="search"
        app:showAsAction="always"/>
    <item
        android:id="@+id/refresh_btn"
        android:icon="@drawable/ic_refresh_white_24dp"
        android:title="refresh"
        app:showAsAction="always"/>
    <item
        android:id="@+id/action_item_1"
        android:title="item 1"
        app:showAsAction="never"/>
    <item
        android:id="@+id/action_item_2"
        android:title="item 2"
        app:showAsAction="never"/>
</menu>

可以看到,我在这里定义了四个 item,分别对应着搜索,刷新和两个隐藏的子菜单。为何说是隐藏的子菜单?后两个 item 和 前两个 item 有什么区别吗?显然,区别在于每个 item 最后一句的代码app:showAsAction="",可选的值有但不限于:

  • always (显示在 Toolbar 上)
  • never (二级菜单,隐藏在最右边的三点图标内)
  • ifRoom (Toolbar 上有足够的空间才显示出来)

注意:app:showAsAction="" 的命名空间要是 app,若改其命名空间为 android,会报错

2.2 再在 Java 代码中使用菜单的 xml

toolbar.inflateMenu(R.menu.tool_bar_menu);

2.3 给 menu 设置监听

toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { //toolbar上菜单的监听事件
    @Override
    public boolean onMenuItemClick(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.search_btn:
                Toast.makeText(MainActivity.this, "click search button", Toast.LENGTH_SHORT).show();
                break;
            case R.id.refresh_btn:
                Toast.makeText(MainActivity.this, "click refresh button", Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_item_1:
                Toast.makeText(MainActivity.this, "click item1", Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_item_2:
                Toast.makeText(MainActivity.this, "click item2", Toast.LENGTH_SHORT).show();
        }
        return true;
    }
});

如此一来,就不必在 activity 中另建菜单。

注意:如果通过 Toolbar 这样的方法创建 menu 之后,再在 Java 代码中将 Toolbar 设为 actionBar 的话,会让这个 menu 失效,即看不到 menu 啦,悲伤 ╮(╯_╰)╭,这实在是个坑,当初找了很久才找出这个 bug...所以大家要是选择通过 Toolbar 设置菜单,就不要再将其设为 acitonBar 了。

3. 与 AppBarLayout 联合

借助 CoordinatorLayout 后,Toolbar 与 AppBarLayout 的联合使用,可比较简单地实现一些酷炫的交互。当然,要想使用 CoordinatorLayout,要先引入 Desinn 库的依赖:

compile 'com.android.support:design:23.1.1'

关于 CoordinatorLayout,可以看这篇文章:CoordinatorLayout与滚动的处理,我这里就当作补充吧,从实践角度讲一下细节。

3.1 滑动隐藏 Toolbar

亮图:

滑动隐藏 Toolbar
滑动隐藏 Toolbar

上代码:

<android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        
        <android.support.v7.widget.Toolbar
            android:id="@+id/tool_bar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways"
            app:title="Title" />
            
        <android.support.design.widget.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabTextColor="#83c7fd"
            app:tabSelectedTextColor="#ffffff"
            app:tabIndicatorColor="#ffffff"
            app:tabIndicatorHeight="3dp"/>
            
    </android.support.design.widget.AppBarLayout>
    
    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
        
</android.support.design.widget.CoordinatorLayout>

结构上,CoordinatorLayout 里包含 AppBarLayout 和 ViewPager,其中 AppBarLayout 包含着 Toolbar 和 TabLayout。Toolbar 里的 app:layout_scrollFlags="scroll|enterAlways",和 ViewPager 里的 app:layout_behavior="@string/appbar_scrolling_view_behavior",这两句是实现联动效果的关键!
当然,其中的 app:layout_scrollFlags="" 有好几个值可选:

  • scroll
  • exitUntilCollapsed
  • enterAlways
  • enterAlwaysCollapsed
  • exitUntilCollapsed

在这里,要想实现 Toolbar 的隐藏,
Toolbar 的 app:layout_scrollFlags="" 应选择 scroll|enterAlways,而 TabLayout 因不需滚动出屏幕,则不用设置该属性。
关于其他几个的区别,读者可自行试试。

注意:ViewPager 里面的 Fragment,要么是 RecycleView,要么父布局是 NestedScrollView,总而言之,是能与 CoordinatorLayout 联动的部件。

关于 TabLayout 和 ViewPager ,有时间的话可以再写篇文章了,给自己挖坑 orz,不过还是挺好的,多写写博客嘛 _

3.2 实现 Toolbar 的折叠效果

要想实现折叠效果,就要在 CoordinatorLayout,AppBarLayout 和 Toolbar 的基础上,再加上 CollapsingToolbarLayout 了。顾名思义,CollapsingToolbarLayout 就是实现 Toolbar 折叠的关键所在!

废话少说,先上代码:

<android.support.design.widget.CoordinatorLayout
    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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        app:theme="@style/AppTheme.AppBarOverlay">
        
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/coolapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="@color/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:expandedTitleMarginStart="16dp"
            app:expandedTitleMarginBottom="10dp"
            app:titleEnabled="true"
            app:title="Hello">
            
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                android:src="@drawable/croatian_coast"/>
            
            <android.support.v7.widget.Toolbar
                android:id="@+id/rv_tool_bar"
                app:popupTheme="@style/AppTheme.PopupOverlay"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:navigationIcon="@drawable/ic_arrow_back_white_24dp"
                app:title="Hi">
            </android.support.v7.widget.Toolbar>
            
        </android.support.design.widget.CollapsingToolbarLayout>
        
    </android.support.design.widget.AppBarLayout>
    
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
    </android.support.v7.widget.RecyclerView>
    
    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_anchor="@id/app_bar"
        app:layout_anchorGravity="bottom|right"
        android:layout_marginRight="16dp"
        android:src="@drawable/ic_search_white_24dp"/>
        
</android.support.design.widget.CoordinatorLayout>

可以看到,主父布局仍然是 CoordinatorLayout。只需要把 Toolbar 放进 CollapsingToolbarLayout 里面,然后再一起放进 AppBarLayout 里就行。难道这就可以实现折叠效果吗?不不不,图样图森破!

这里面的关键代码是 ImageView 里的:

app:layout_collapseMode="parallax"

和 Toolbar 里的:

app:layout_collapseMode="pin"

parallax,是指视差滚动
pin,指固定不动

如此一来就可实现折叠效果,接下来再简单说下 CollapsingToolbarLayout 里的一些重要属性:

  • app:contentScrim=""
    srim,Google 翻译是麻布。通过实践,我想,这里的意思应该是 Toolbar 折叠后的背景,所以可填的值为颜色,或者图片背景
  • app:layout_scrollFlags=""
    这个属性在上面的3-1 滑动隐藏 Toolbar有介绍。在这里,如果没有设置这个属性,则不会产生折叠效果,布局会固定在原地。要想实现图片上折叠的效果,应选择scroll|exitUntilCollapsed,其他几个选项的区别就不一一列出了。
  • app:expandedTitleMargin
    这个是一系列的属性,包括MarginStartMarginBottom等等,顾名思义,这些属性是调整展开后 title 的位置的
  • app:title=""
    显然,这个属性是设置 Toolbar 的 title 的,可能你会问:为什么不在 Toolbar 里面设置 title 呢?有什么区别呢?我在这里做一个对比吧。

CollapsingToolbarLayout 里:

app:titleEnabled="true"
app:title="Hello"

Toolbar 里:

app:title="Hi"

来看看效果:


Toolbar 1
Toolbar 1

然后我们把 CollapsingToolbarLayout 改一下:

app:titleEnabled="false"

再看下效果:


Toobar 2
Toobar 2

对比之下,就很清楚了。同时在 CollapsingToolbarLayout 和 Toolbar 都设置了 title 的话,前者的 title 会覆盖后者的,即只显示前者的 title。

关于 Toolbar,以后遇到什么问题,我会更新在此。

感谢阅读!

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

推荐阅读更多精彩内容