从 Android 3.0 (API 11) 开始,默认主题背景的 Activity 均使用 ActionBar 作为应用栏,随着 Android 版本的演化,应用栏的功能逐渐添加到 ActionBar 中,不能版本的 Android 系统 ActionBar 行为不同。
Toolbar 类的出现能够确保应用在最大范围的设备保持一致的行为,能够运行在 Android 2.1(API 7)或更高的设备上提供 Material Design 体验,而 ActionBar 除非运行在 Android 5.0(API 21)或更高版本。

使用步骤

1. 首先要引入 v7 支持包,在 build.gradle 中配置如下代码:

compile 'com.android.support:appcompat-v7:24.1.1'

随着 Android 9.0(API 28)的发布,有一个名为 AndroidX 的支持库的新版本,它包含现有的支持库,还包含最新的 Jetpack 组件。如果使用 API 28 及以上,则不用引入 v7 支持包。

2. 在 AndroidManifest 文件中,设置主题为 NoActionBar,防止应用使用 ActionBar,配置代码如下:

<application
    android:theme="@style/AppTheme">
</application>

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- toolbar颜色 -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <!-- 状态栏颜色 -->
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
</style>

3. 向 Activity 的布局添加一个 Toolbar,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">
    
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/my_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"     //官方指定 MD 高度
        android:background="?attr/colorPrimary"
        app:navigationIcon="?attr/homeAsUpIndicator"    //设置 Navigation 图标
        app:contentInsetStartWithNavigation="0dp"       //titile 与 NavigationIcon 距离     
        app:titleTextAppearance="@style/Toolbar.TitleText"   //设置 title 字体大小
        app:popupTheme="@style/popu_theme"    //设置 menu 样式
        android:theme="@style/toolbar_theme"  //设置 toolbar 样式
        />
        
</LinearLayout>

4. Toolbar 相关配置

  • 修改 Toolbar 标题字体大小,颜色。
<style name="Toolbar.TitleText" parent="TextAppearance.AppCompat.Title">
     <item name="android:textSize">15sp</item>
     <item name="android:textColor">#ffffff</item>
</style>
  • 修改 Toolbar 图标颜色,标题字体颜色也可以在这里设置。
<style name="toolbar_theme" parent="ThemeOverlay.AppCompat.Light">
    <!--设置标题颜色-->                                                 
    <item name="android:textColorPrimary">#ffffff</item>          
    <!--设置 toolbar 图标颜色-->                                        
    <item name="colorControlNormal">#ffffff</item>                
</style>
  • 修改 Toolbar 上的 menu 背景颜色,字体颜色,以及避免覆盖 toolbar。
<!--设置 menu 背景颜色,字体颜色-->                                                            
<style name="popu_theme" parent="ThemeOverlay.AppCompat.Light">                     
    <item name="android:background">#ffffff</item>                                  
    <item name="android:textColor">#ff0000</item>                                   
    <item name="overlapAnchor">false</item>   //不覆盖锚点           
</style>

5. 在 Activity 的 onCreate() 方法中调用 setSupportActionBar()方法。

protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_toolbar);
        Toolbar myToolbar = findViewById(R.id.my_toolbar);
        setSupportActionBar(myToolbar);             //将 Toolbar 设为 Activity 的应用栏
        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);  //显示 Navigation
}

6.加载 Menu 并添加点击事件。

  • 在项目的 res/menu/ 目录下,创建 menu 布局文件,本例创建 toolbar.xml。
<?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/action_favorite"
        android:icon="@mipmap/ic_launcher"
        android:title="喜欢"
        app:showAsAction="ifRoom"
        />
    <item
        android:id="@+id/action_set"
        android:title="设置"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="withText" />
    <item
        android:id="@+id/action_share"
        android:title="分享"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="withText"
        />

</menu>

//app:showAsAction 属性
//1.ifRoom 如果 Toolbar 上有足够的空间,操作会显示为按钮,如果没有空间,则会发送到溢出菜单。
//2.never  此操作会始终显示在溢出菜单中。
//3.always 此操作会始终显示在 ToolBar 上。
//4 withText 使菜单项和它的图标,菜单文本一起显示。
  • 加载 menu 布局文件,在 Activity 中重写 onCreateOptionsMenu(Menu menu) 方法。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.toolbar, menu);
    return super.onCreateOptionsMenu(menu);
}
  • 选择菜单子项时响应操作,在 Activity 中重写 onOptionsItemSelected() 方法。
@Override                                                                                
public boolean onOptionsItemSelected(@NonNull MenuItem item) {                           
    switch (item.getItemId()) {                                                          
        case R.id.action_favorite:                                                       
            Log.d("ToolbarActivity", "onOptionsItemSelected: action_favorite");          
            return true;                                                                 
        case R.id.action_set:                                                            
            Log.d("ToolbarActivity", "onOptionsItemSelected: action_set");               
            return true;                                                                 
        case R.id.action_share:                                                          
            Log.d("ToolbarActivity", "onOptionsItemSelected: action_share");             
            return true;                                                                 
        default:                                                                         
            return super.onOptionsItemSelected(item);                                    
    }                                                                                    
}
  • 显示 menu 的 icon ,通过反射的方法。
@Override                                                                                          
public boolean onPreparePanel(int featureId, @Nullable View view, @NonNull Menu menu) {            
    if (menu != null) {                                                                            
        if (menu.getClass().getSimpleName().equals("MenuBuilder")) {                               
            try {                                                                                  
                Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible",       
                        Boolean.TYPE);                                                             
                method.setAccessible(true);                                                        
                method.invoke(menu, true);                                                         
            } catch (Exception e) {                                                                
                e.printStackTrace();                                                               
            }                                                                                      
        }                                                                                          
    }                                                                                              
    return super.onPreparePanel(featureId, view, menu);                                            
}

最终实现效果图如下所示:

android progressbar 设置style android actionbar toolbar_Android


7.Fragment 中加载 Menu 并添加点击事件。

  • 由于 Fragment 中没有 setSupportActionBar() 方法,所以要托管到其 Activity 来处理。
AppCompatActivity appCompatActivity = (AppCompatActivity) getActivity();
appCompatActivity.setSupportActionBar(toolbar);
  • 让 Activity 知道有 menu 要加载,此时 Fragment 可加载完成。
setHasOptionsMenu(true);