《安卓项目实战之:ToolBar的使用介绍》
ToolBar简介
Toolbar是谷歌在2014年Google IO 大会上推出的一套全新的设计规范Material Design中的控件之一,主要是用来在android 5.0之后代替Android传统的标题栏ActionBar的,引入在android-support-v7兼容包下,使用ToolBar能实现和ActionBar一样的效果,并且ToolBar继承自ViewGroup,使用起来也是更加的灵活。
ToolBar的组成如下图:
对应的布局文件属性设置如下:
<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" app:popupTheme="@style/toolBar_pop_item" >
对导航图标navigationIcon设置点击监听:
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(); } });
如果你添加了 setSupportActionBar(toolbar); 这行代码,那么 toolbar.setNavigationOnClickListener监听方法,要放到其后面,否则点击事件,监听不到的。如果你用不到ActionBar的一些特性的话,建议setSupportActionBar(toolbar); 这行代码不用添加了。
关于菜单及自定义View的使用会在下面详细介绍。
为什么会有ToolBar?
传统的ActionBar在每次Android SDK版本更新时都会做一些改变,所以在不同的手机上往往会展示出不一样的效果,导致很严重的碎片化问题,GooGle官方为了解决这种碎片化问题在某次更新android-support-v7兼容包时引入了ToolBar,用来替代ActionBar,以达到不同版本展示效果的高度一致性。
为什么要使用ToolBar?
1,首先上面也说了如果要实现标题栏,优先考虑使用ToolBar,可以有效的解决兼容性问题。
2,有很多人有这样的疑问,我自己写一个RelativeLayout或者其他什么布局都能实现标题栏,为什么非要用Toolbar呢?当然了首先它是GooGle官方推荐的标题控件,其次是使用ToolBar和其他MD设计风格的控件组合使用,能实现一些比较炫的效果,比如Toolbar+NestScrollView,Toolbar+DrawerLayout + NavigationView等等;
ToolBar在实际项目中的使用
1,因为ToolBar位于V7包下,所以首先我们要确保应用引入了V7包,使用V7包下的ToolBar控件这样就可以兼容到5.0以下的版本。
2,设置项目的主题为NoActionBar。
3,在布局文件中使用:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:background="@color/colorAccent" android:layout_width="match_parent" app:navigationIcon="@drawable/ic_arrow_back_white" app:title="我是ToolBar" app:titleTextColor="#fff" android:layout_height="?attr/actionBarSize"> </android.support.v7.widget.Toolbar> </RelativeLayout>
上面ToolBar的高度可以给个固定值也可以使用?attr/actionBarSize指定为ActionBar的高度一致。
Activity中代码也很简单,初始化控件Toolbar,然后设置导航图标的点击事件监听,需要注意的是如果添加了 setSupportActionBar(toolbar); 这行代码,那么 toolbar.setNavigationOnClickListener监听方法,要放到其后面,否则点击事件,监听不到的,或者如果使用不到ActionBar的特性的话,这行代码我们完全可以不添加照样可以监听到导航按钮点击监听。
最终效果如下图:
设置菜单选项
1,首先在res目录下创建menu文件夹,然后定义一个toolbar_menu.xml文件,用于toolbar标题栏中各种action按钮的展示:
<?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"> <!--orderInCategory菜单项的优先级,也就是顺序,只能设置正整数,数值越大菜单项越靠前--> <item android:id="@+id/item1" android:orderInCategory="100" android:title="搜索" android:icon="@drawable/icon_search" app:showAsAction="ifRoom" /> <item android:id="@+id/item2" android:orderInCategory="100" android:title="通知" android:icon="@drawable/icon_notify" app:showAsAction="ifRoom"/> <item android:id="@+id/item3" android:orderInCategory="100" android:title="设置" app:showAsAction="never"/> <item android:id="@+id/item4" android:orderInCategory="100" android:title="关于" app:showAsAction="never"/> </menu>
可以看出菜单中每个Item主要设置四个属性:id(用于监听区分),title(菜单名称),icon(图标),以及showAsAction(控制item在标题栏上的展示形式),默认Toolbar中显示的菜单项只会显示图标,设置的title不显示,但是我们长按该图标会发现title会显示在图标下方,另外溢出菜单中也只会显示菜单的title,不显示图标。
showAsAction属性我们主要关心如下三个取值:
1,always:表示永远显示在Toolbar中,如果屏幕空间不够则不显示。
2,ifRoom:如果toolbar上还有空间的话就会显示优先级高的菜单项在toolbar上,否则将剩下的显示在溢出菜单中 。
3,never:表示永远不显示在Toolbar中,而是一直显示在溢出菜单中。
2,在代码中关联Toolbar和menu菜单,并设置菜单的点击事件监听:
// 关联toolbar和menu,只需这一句代码菜单就可以正常显示了 toolBar.inflateMenu(R.menu.toolbar_menu); // 手动设置溢出菜单项的图标 toolBar.setOverflowIcon(getResources().getDrawable(R.drawable.ic_menu_over_flow)); // 设置菜单点击事件监听 toolBar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()){ case R.id.item1: Toast.makeText(ToolbarActivity.this, "菜单项1", Toast.LENGTH_SHORT).show(); break; case R.id.item2: Toast.makeText(ToolbarActivity.this, "菜单项2", Toast.LENGTH_SHORT).show(); break; case R.id.item3: Toast.makeText(ToolbarActivity.this, "菜单项3", Toast.LENGTH_SHORT).show(); break; case R.id.item4: Toast.makeText(ToolbarActivity.this, "菜单项4", Toast.LENGTH_SHORT).show(); break; default: break; } return false; } });
经过以上步骤后菜单就添加成功了,最终效果如下图:
因为在menu配置文件中我们设置了最后两个菜单项的showAsAction为never,所以默认会在标题栏的最右侧显示一个溢出菜单选项,该溢出菜单项的图标默认为灰色的竖排显示的三个小圆点,我们可以更改该图标,只要添加如下这句代码即可:
1toolBar.setOverflowIcon(getResources().getDrawable(R.drawable.ic_menu_over_flow));
2
3
溢出菜单选项用来展示showAsAction属性为never和空间不足以展示的菜单项,当然了如果没有未被展示的item,这里就不会出现这个图标,然后我们点击溢出图标,系统默认的弹出样式是这样的:
首先我们发现溢出菜单弹出框中默认只显示菜单的title,不显示图标,如果我们想要溢出菜单的弹出框中除了能显示title外,还想显示图标,那么也是可以的,这里提供两种方案,具体请查看博客:https://blog.csdn.net/shangming150/article/details/77914110
其次我们可以看到默认的溢出菜单的弹出框样式非常丑,并且遮挡住了Toolbar标题栏,但是没关系,我们可以通过在布局文件中指定app:popupTheme="@style/menu_bg"属性来指定一个自定义的样式,至于这个样式具体能定义哪些内容,下面给出一个示例:
<!--自定义toolbar菜单样式--> <style name="toolbarMenuStyle" parent="@style/Widget.AppCompat.PopupMenu.Overflow"> <!-- 是否覆盖锚点,默认为true,即盖住Toolbar --> <item name="overlapAnchor">false</item> <!-- 弹出层背景颜色 --> <item name="android:popupBackground">@color/material_deep_teal_500</item> <!-- 弹出层垂直方向上的偏移,负值会覆盖toolbar --> <item name="android:dropDownVerticalOffset">5dp</item> <!-- 弹出层水平方向上的偏移,即距离屏幕左边的距离,负值会导致右边出现空隙 --> <item name="android:dropDownHorizontalOffset">-2dp</item> <!--文字颜色--> <item name="android:textColor">@color/white</item> </style>
定义好样式后需要在app的主题中引用该样式,才能改变溢出框内的文字颜色,如下:
<!-- Base application theme. --> <style name="AppTheme" parent="Base.AppTheme"> <!--指定toolbar弹出菜单样式--> <item name="actionOverflowMenuStyle">@style/toolbarMenuStyle</item> </style>
最后在toolbar中引用:
<android.support.v7.widget.Toolbar android:background="@color/material_deep_teal_500" android:id= "@+id/toolbar" android:layout_width="match_parent" app:popupTheme="@style/toolbarMenuStyle" android:layout_height="?attr/actionBarSize"> </android.support.v7.widget.Toolbar>
这样溢出菜单的弹出框样式我们就修改完成了,具体再根据项目需求作相应的更改。
标题居中问题和自定义Toolbar
如果项目要求标题栏上的标题居中显示,通过查看查看api我们发现toolbar没有提供标题居中的方法,仅仅是提供了使其距左右,上下边距大小的方法。
不过不用担心,之前文中提到过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" /> </RelativeLayout> </android.support.v7.widget.Toolbar>
上面的布局文件中没有使用默认的导航图标而是自定义了ImageView,如果想使用默认的导航图标也是可以的,布局修改如下即可:
<android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/colorAccent"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="标题" android:textColor="@color/white" android:textSize="22sp" /> </android.support.v7.widget.Toolbar>
注意此时 TextView 控件的宽和高都是自适应大小,java 代码中此行代码setSupportActionBar(toolbar);就不要添加了,否则就会显示不正常。
除非用到ActionBar的特性不然不推荐添加这行代码。
关于Toolbar就先介绍这么多,关于Toolbar和DrawerLyout实现侧滑动画效果,时间关系后续再来完善。

浙公网安备 33010602011771号