1、首先在配置文件中加入Toolbar控件
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="@drawable/ic_arrow_back"
app:titleMarginStart="0dp">
</androidx.appcompat.widget.Toolbar>
指定height为?attr/actionBarSize,说明和系统默认的Toolbar高度相同,设置app:navigationIcon指定导航图标,其实这仅仅是个按钮,具体的点击事件还是要自己处理,然后一定要把主题改成NoActionBar的类型,因为现在使用的是我们自己的Toolbar了,系统自带的ActionBar就不需要了。效果图:
可以看到navigationIcon在左上角,这里还没有title,可以在xml文件中直接指定Toolbar的title,或者是通过findViewById找到Toolbar,再setTitle。
我们先来看一下Toolbar的构成图:
可以看出正因为Toolbar的如此复杂,因此可扩展性也就很高。
下面一一介绍各个部分:
1. Home部分
就是上面说的NavigationIcon的位置,可以对此添加点击事件
一般此按钮作用为结束当前Activity
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
另外,也可以使用ActionBar的方式监听此消息,可能google为了兼容之前的版本,使得可以使用ActionBar的方式来操纵Toolbar,首先使当前Activity以ActionBar的形式来操纵Toolbar
setSupportActionBar(mToolbar);
然后在Activity中监听点击事件:
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int itemId = item.getItemId();
switch (itemId) {
case android.R.id.home:
finish();
break;
}
2. Logo部分
这个部分用到的可能性一般不大,就是设置一个图标,没什么讲的。
3. Title部分
这个部分很重要,用来设置这个界面的标题,但用起来还是很简单的,可以在xml文件,也可以在代码里面动态设置:
mToolbar.setTitle("Title");
此处讲一个问题,就是默认情况下navigationIcon和Title之间会有一个间隔,打开手机的开发者模式。显示layout_bounds,可以清晰的显示间距:
这个间距如何消除呢?
设置Toolbar的这两个属性即可:
app:contentInsetStartWithNavigation="0dp"
app:titleMarginStart="0dp"
具体原因有兴趣的可以查看Toolbar的源代码,在onLayout流程里有。
5. CustomeView部分
这个部分,顾名思义就是自定义的部分了,比如我们想让title显示在中间那怎么办?直接在中间加一个TextView居中就行了,左边的title部分就不设置了,如下:
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
app:contentInsetStartWithNavigation="0dp"
app:titleMarginStart="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="@drawable/ic_arrow_back">
<TextView
android:id="@+id/title"
android:text="Center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="20sp" />
</androidx.appcompat.widget.Toolbar>

其实Toolbar就是一个ViewGroup,我们把TextView居中显示就行了。看起来就是居中的title了。
6. Menu/OverFlow部分
剩下的部分其实是一样的,Menu显示不下的地方一般就放到OverFlow中,要使用这一部分,我们先要定义一个menu资源文件:
我定义了一个more.xml的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">
<item
android:id="@+id/share"
android:icon="@drawable/ic_share"
android:title="share"
app:showAsAction="always" />
<item
android:id="@+id/delete"
android:icon="@drawable/ic_delete"
android:title="delete"
app:showAsAction="always" />
<item
android:id="@+id/_1"
android:title="1"
app:showAsAction="never" />
<item
android:id="@+id/_2"
android:title="2"
app:showAsAction="never" />
<item
android:id="@+id/_3"
android:title="3"
app:showAsAction="never" />
</menu>
其中有5个item,title部分指定了每个item的名称,showAsAction一般指定这么几种值:
app:showAsAction="always" //以icon的形式显示在menu部分
app:showAsAction="never" //以title的形式显示在popMenu中
app:showAsAction="ifRoom" //如果menu部分可以放得下,就放在menu部分,否则放入popMenu中
有了资源文件,就要和Toolbar挂钩,并且设置相应的点击事件了:
mToolbar.inflateMenu(R.menu.more);
final Context mContext = this;
mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
int itemId = item.getItemId();
switch (itemId) {
case R.id.delete:
Toast.makeText(mContext, "click delete", Toast.LENGTH_SHORT).show();
break;
case R.id.share:
Toast.makeText(mContext, "click share", Toast.LENGTH_SHORT).show();
break;
case R.id._1:
Toast.makeText(mContext, "click 1", Toast.LENGTH_SHORT).show();
break;
case R.id._2:
Toast.makeText(mContext, "click 2", Toast.LENGTH_SHORT).show();
break;
case R.id._3:
Toast.makeText(mContext, "click 3", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
});


当然,也可以用ActionBar的形式来做此事,在最后demo中,会分别以Toolbar和ActionBar的形式来做上面所有的操作。
最后再说一下Toolbar title和popupMenu的主题,在Toolbar中可以指定title字体的样式,比如指定字体20dp,颜色为白色,可以这么做,先定义一个主题,然后在Toolbar中指定
<style name="ToolbarTitle" parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textColor">#FFFFFF</item>
<item name="android:textSize">20sp</item>
</style>
指定title样式
app:titleTextAppearance="@style/ToolbarTitle"
效果图:
相应,也可以改变PopupMenu的样式,比如我们想让popupMenu的背景色为黑色,字体为白色,那么我们可以这么做,首先定义一个主题:
<style name="ToolbarPopTheme" parent="Widget.AppCompat.PopupMenu">
<item name="android:background">#000000</item>
<item name="android:textColor">#FFFFFF</item>
</style>
然后在Toolbar中指定:
app:popupTheme="@style/ToolbarPopTheme"
效果图:
demo地址:https://github.com/whoami-I/XToolbar.git