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
亮图:
上代码:
<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
这个是一系列的属性,包括MarginStart
,MarginBottom
等等,顾名思义,这些属性是调整展开后 title 的位置的 -
app:title=""
显然,这个属性是设置 Toolbar 的 title 的,可能你会问:为什么不在 Toolbar 里面设置 title 呢?有什么区别呢?我在这里做一个对比吧。
CollapsingToolbarLayout 里:
app:titleEnabled="true"
app:title="Hello"
Toolbar 里:
app:title="Hi"
来看看效果:
然后我们把 CollapsingToolbarLayout 改一下:
app:titleEnabled="false"
再看下效果:
对比之下,就很清楚了。同时在 CollapsingToolbarLayout 和 Toolbar 都设置了 title 的话,前者的 title 会覆盖后者的,即只显示前者的 title。
关于 Toolbar,以后遇到什么问题,我会更新在此。
感谢阅读!