众所周知,Actionbar由于其扩展性差,已经逐步被Toolbar取代,官方也推荐使用Toolbar,下面我们来看一下toolbar的使用,网上的很多对toolbar的使用只是简单的介绍,在本篇文章中,我还加入了一些常用的技巧:
在使用toolbar之前首先修改application或者activity的主题为不带Actionbar的主题,这里我们使用NoActionBar
首先是在布局中引用:
<android.support.v7.widget.Toolbar
android:id="@+id/toolBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:theme="@style/ThemeOverlay.AppCompat.Light"
></android.support.v7.widget.Toolbar>
注意不要忘了:
xmlns:app=”http://schemas.android.com/apk/res-auto”
然后在activity里加入以下代码:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolBar);
setSupportActionBar(toolbar);
这两句话就是让toolbar替代actionbar,此时启动程序就已经显示出来了
现在的toolbar只有一个标题显示,下面我们来加入一些图标:
首先我们要新建一个menu文件夹并创建toolbar.xml资源文件,toolbar.xml里的具体内容为:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:icon="@mipmap/ic_launcher"
android:title="backup"
android:id="@+id/backup"
app:showAsAction="always"/>
<item
android:icon="@mipmap/ic_launcher"
android:title="delete"
android:id="@+id/delete"
app:showAsAction="ifRoom"/>
<item
android:icon="@mipmap/ic_launcher"
android:title="setting"
android:id="@+id/setting"
app:showAsAction="never"/>
</menu>
这里面有3个item,在介绍之前首先说说app:showAsAction这个属性;
首先我们来介绍一下他都有那些属性:
- never:隐藏在overflow中
- ifRoom:如果有空间就显示否则隐藏
- always:总是显示
- collapseActionView:当前控件点开之后占据整个ToolBar空间
第一个item是总是显示toolbar上,第二个item是如果toolbar还有空间就显示,否则隐藏在overflow中,第三个item是隐藏在overflow中。
接着我们在activity中加入如下代码引入到toolbar中:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar, menu);
return true;
}
效果如下:
接着我们对这些item进行点击监听:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.backup:
Toast.makeText(MainActivity.this, "backUp", Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
Toast.makeText(MainActivity.this, "delete", Toast.LENGTH_SHORT).show();
break;
case R.id.setting:
Toast.makeText(MainActivity.this, "setting", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
很简单,就不用我多说了;另外也可以通过下面的方法设置监听:
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.backup:
Toast.makeText(MainActivity.this, "backUp", Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
Toast.makeText(MainActivity.this, "delete", Toast.LENGTH_SHORT).show();
break;
case R.id.setting:
Toast.makeText(MainActivity.this, "setting", Toast.LENGTH_SHORT).show();
break;
}
return false;
}
});
下面我们来讲一些toolbar使用的技巧。
返回按钮
在toolbar的最左边显示一个按钮,默认是一个返回图标,可以修改图标。
ActionBar actionBar = getSupportActionBar();
//显示返回按钮以及返回按钮的点击事件
actionBar.setDisplayHomeAsUpEnabled(true);
//改变返回按钮的默认图标
//actionBar.setHomeAsUpIndicator(R.mipmap.ic_launcher);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
点击事件也可以在onOptionsItemSelected中通过R.id.home来监听。
效果如下:
添加Action View
ActionView是一种可以在toolbar中替换Action按钮的控件,它可以允许用户在不切换界面的情况下通过toolbar完成一些较为丰富的操作。比如说,你需要完成一个搜索功能,就可以将SeachView这个控件添加到toolbar中。
在toolbar.xml中添加一个item:
<item app:actionViewClass="android.support.v7.widget.SearchView"
android:title="search"
android:id="@+id/search"
app:showAsAction="ifRoom|collapseActionView"/>
指定searchView的包名,ifRoom|collapseActionView的第一个属性不必多说,第二个属性的意思是该控件可以被合并成一个Action按钮。。
我们看一下效果:
如果你还希望在代码中对SearchView的属性进行配置(比如添加监听事件等),完全没有问题,只需要在onCreateOptionsMenu()方法中获取该ActionView的实例就可以了,代码如下所示:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
// 配置SearchView的属性
......
return super.onCreateOptionsMenu(menu);
}
修改字体图标颜色
toolbar上的字体和图标颜色有黑色和白色两种,他们的出现取决于toolbar的 app:theme这个属性,也就是toolbar的主题,如果是暗色的主题就会出现白色的字体图标,反之亮色的主题就会出现黑色的字体图标。我们看看我们创建toolbar时使用的主题:
app:theme=”@style/ThemeOverlay.AppCompat.Light”
这是一个亮色的主题,所以文字图标的颜色是黑色的,如果想让他变成白色只需修改一个暗色的主题,比如:
app:theme=”@style/ThemeOverlay.AppCompat.Dark.ActionBar”
修改overflow的背景颜色和图标
overflow的主题样式是由app:popupTheme这个属性取决的,他和app:theme一样受主题效果的影响,不同的是它可以自主的设定背景颜色:
<style name="OverflowMenuStyle" parent="@style/Widget.AppCompat.PopupMenu.Overflow">
<!-- 是否覆盖锚点,默认为true,即盖住Toolbar -->
<item name="overlapAnchor">false</item>
<!-- 弹出层背景颜色 -->
<item name="android:popupBackground">@color/colorPrimary</item>
<!-- 弹出层垂直方向上的偏移,即在竖直方向上距离Toolbar的距离,值为负则会盖住Toolbar -->
<item name="android:dropDownVerticalOffset">0dp</item>
<!-- 弹出层水平方向上的偏移,即距离屏幕左边的距离,负值会导致右边出现空隙 -->
<item name="android:dropDownHorizontalOffset">0dp</item>
</style>
最后为toolbar添加属性:
app:popupTheme=”@style/OverflowMenuStyle”
修改图标也是在style中设置:
<style name="OverflowButtonStyle" parent="@android:style/Widget.Holo.Light.ActionButton.Overflow">
<item name="android:src">@drawable/ic_add_black_24dp</item>
</style>
下面我们把这两个设置整合在一起,在res的values文件夹中打开styles.xml,为toolbar创建一个style,名字是toolbar_theme:
<style name="toolbar_theme" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<!--改变overflow的默认图标-->
<item name="android:actionOverflowButtonStyle">@style/OverflowButtonStyle</item>
<!--修改overflow展开后的样式-->
<item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item>
</style>
<style name="OverflowButtonStyle" parent="@android:style/Widget.Holo.Light.ActionButton.Overflow">
<item name="android:src">@drawable/ic_add_black_24dp</item>
</style>
<style name="OverflowMenuStyle" parent="@style/Widget.AppCompat.PopupMenu.Overflow">
<!-- 是否覆盖锚点,默认为true,即盖住Toolbar -->
<item name="overlapAnchor">false</item>
<!-- 弹出层背景颜色 -->
<item name="android:popupBackground">@color/colorPrimary</item>
<!-- 弹出层垂直方向上的偏移,即在竖直方向上距离Toolbar的距离,值为负则会盖住Toolbar -->
<item name="android:dropDownVerticalOffset">0dp</item>
<!-- 弹出层水平方向上的偏移,即距离屏幕左边的距离,负值会导致右边出现空隙 -->
<item name="android:dropDownHorizontalOffset">0dp</item>
</style>
上面的代码首先新建一个主style:toolbar_theme
然后新建一个设置overflow图标的style和一个overflow背景颜色的style
再将这两个style添加到toolbar_theme中
最后我们给toolbar的Theme设置为toolbar_theme
app:theme=”@style/toolbar_theme”
Overflow中的选项显示图标
overflow中的Action按钮应不应该显示图标,是由MenuBuilder这个类的setOptionalIconsVisible方法来决定的,如果我们在overflow被展开的时候给这个方法传入true,那么里面的每一个Action按钮对应的图标就都会显示出来了。调用的方法当然仍然是用反射了,代码如下所示:
@Override
protected boolean onPrepareOptionsPanel(View view, Menu menu) {
if (menu != null) { if(menu.getClass().getSimpleName().equals("MenuBuilder")) {
try {
Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
return super.onPrepareOptionsPanel(view, menu);
}
隐藏overflow
隐藏overflow非常简单:
在onPrepareOptionsMenu方法中返回false就可以了。
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
return false;
}
标题居中
在查阅过大量资料后发现让标题居中使用最多的也是最简单的方法是隐藏原有的标题,然后在toolbar中添加一个textview:
<android.support.v7.widget.Toolbar
android:id="@+id/toolBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:theme="@style/ThemeOverlay.AppCompat.Light"
>
<TextView
android:layout_centerInParent="true"
android:layout_gravity="center"
android:maxLines="1"
android:textSize="20sp"
android:textColor="#ffffff"
android:text="shanshui"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</android.support.v7.widget.Toolbar>
当然我们还需要隐藏原有的标题:
actionBar.setDisplayShowTitleEnabled(false);