Android Toolbar 开发总结
作为Android开发者,你一定绕不开导航栏的实现——Google在Android 5.0推出的Toolbar凭借高灵活性,早已成为取代传统ActionBar的首选方案。本文我将结合自己的实战踩坑经验,从基础用法到实战仿知乎界面,带你彻底吃透Toolbar的使用技巧。
一、为什么选择Toolbar?
相比固定在Activity顶部、定制性差的ActionBar,Toolbar的优势堪称碾压:
- 可自由放置在界面任意位置,不再受顶部限制
- 支持自定义导航图标、App Logo、标题/子标题
- 可嵌入任意自定义控件(如TextView、Button等)
- 完美兼容Action Menu,且样式高度可定制
- 提供向下兼容方案(v7兼容包),适配低版本系统
二、Toolbar基础使用实战
1. 环境准备
首先确保工程引入appcompat-v7兼容包(新版AndroidX对应androidx.appcompat:appcompat),我们将使用androidx.appcompat.widget.Toolbar(替代旧版android.support.v7.widget.Toolbar)进行开发,保证向下兼容性。
2. 布局文件配置
创建activity_toolbar.xml,核心是添加Toolbar控件,并可直接嵌入自定义View:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:toolbar="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 核心Toolbar控件 -->
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
<!-- 自定义命名空间设置属性(关键!避免属性失效) -->
toolbar:navigationIcon="@mipmap/ic_drawer_home"
toolbar:logo="@mipmap/ic_launcher"
toolbar:title="主标题"
toolbar:subtitle="子标题">
<!-- 嵌入自定义控件 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clock"
android:textColor="@android:color/white"/>
</androidx.appcompat.widget.Toolbar>
</LinearLayout>
3. 配置Action 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">
<!-- 搜索按钮 - 显示在Toolbar上 -->
<item
android:id="@+id/action_search"
android:icon="@mipmap/ic_search"
android:title="搜索"
app:showAsAction="ifRoom"/>
<!-- 通知按钮 - 显示在Toolbar上 -->
<item
android:id="@+id/action_notification"
android:icon="@mipmap/ic_notifications"
android:title="通知"
app:showAsAction="ifRoom"/>
<!-- 更多选项 - 折叠在溢出菜单中 -->
<item
android:id="@+id/action_item1"
android:title="选项1"
app:showAsAction="never"/>
<item
android:id="@+id/action_item2"
android:title="选项2"
app:showAsAction="never"/>
</menu>
4. 代码中初始化Toolbar
创建ToolbarActivity,完成Toolbar的初始化和事件绑定:
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.Toast;
public class ToolbarActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 隐藏系统默认ActionBar(关键!避免重叠)
supportRequestWindowFeature(getWindow().FEATURE_NO_TITLE);
setContentView(R.layout.activity_toolbar);
// 1. 获取Toolbar实例
Toolbar toolbar = findViewById(R.id.toolbar);
// 2. 设置基础样式(也可通过xml的toolbar:xxx属性设置)
toolbar.setNavigationIcon(R.mipmap/ic_drawer_home); // 导航图标
toolbar.setLogo(R.mipmap/ic_launcher); // App Logo
toolbar.setTitle("主标题"); // 主标题
toolbar.setSubtitle("子标题"); // 子标题
// 自定义标题颜色
toolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
toolbar.setSubtitleTextColor(getResources().getColor(android.R.color.white));
// 3. 加载Action Menu
toolbar.inflateMenu(R.menu.menu_toolbar);
// 4. 绑定菜单点击事件
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_search) {
Toast.makeText(ToolbarActivity.this, "点击了搜索", Toast.LENGTH_SHORT).show();
} else if (id == R.id.action_notification) {
Toast.makeText(ToolbarActivity.this, "点击了通知", Toast.LENGTH_SHORT).show();
} else if (id == R.id.action_item1) {
Toast.makeText(ToolbarActivity.this, "点击了选项1", Toast.LENGTH_SHORT).show();
} else if (id == R.id.action_item2) {
Toast.makeText(ToolbarActivity.this, "点击了选项2", Toast.LENGTH_SHORT).show();
}
return true;
}
});
}
}
三、实战踩坑:解决Toolbar常见问题
坑1:XML中Toolbar属性设置无效
问题现象:直接用android:navigationIcon、android:title等属性设置后无效果。
原因:兼容版Toolbar的自定义属性不在默认Android SDK命名空间中,需单独声明。
解决方案:
- 在布局根节点添加自定义命名空间:
xmlns:toolbar="http://schemas.android.com/apk/res-auto" - 将
android:xxx替换为toolbar:xxx(如toolbar:title、toolbar:logo)
坑2:Action Menu文字颜色修改无效
问题现象:设置actionMenuTextColor后,菜单文字颜色未变化。
解决方案:
- 在
styles.xml中自定义Theme:
<style name="ToolbarTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- 替换默认文字颜色(关键!替代actionMenuTextColor) -->
<item name="android:textColorPrimary">@color/red</item>
<!-- 可选:修改文字大小 -->
<item name="android:textSize">16sp</item>
</style>
- 在Toolbar中绑定该Theme:
<androidx.appcompat.widget.Toolbar
...
toolbar:popupTheme="@style/ToolbarTheme"/>
⚠️ 注意:此方法会影响Toolbar内其他控件的默认文字颜色,需单独为控件指定颜色。
四、实战进阶:仿知乎主页Toolbar
掌握基础用法后,我们用Toolbar复刻知乎主页的导航栏效果:
1. 布局文件(activity_zhihu.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:toolbar="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/zhihu_blue"
android:theme="@style/ZhihuToolbarTheme">
</androidx.appcompat.widget.Toolbar>
<!-- 页面主体内容 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerInParent="true"
android:src="@mipmap/ic_zhihu_logo"/>
</RelativeLayout>
</LinearLayout>
2. 自定义Theme(styles.xml)
<!-- 知乎Toolbar主题:替换溢出菜单图标 -->
<style name="ZhihuToolbarTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="actionOverflowButtonStyle">@style/OverflowStyle</item>
</style>
<!-- 自定义溢出菜单图标 -->
<style name="OverflowStyle" parent="Widget.AppCompat.ActionButton.Overflow">
<item name="android:src">@mipmap/ic_menu_more</item>
</style>
3. 菜单文件(menu_zhihu.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_search"
android:icon="@mipmap/ic_search"
android:title="搜索"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_notification"
android:icon="@mipmap/ic_notification"
android:title="通知"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_settings"
android:title="设置"
app:showAsAction="never"/>
<item
android:id="@+id/action_about"
android:title="关于我们"
app:showAsAction="never"/>
</menu>
4. 核心代码(ZhihuActivity.java)
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.os.Bundle;
public class ZhihuActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(getWindow().FEATURE_NO_TITLE);
setContentView(R.layout.activity_zhihu);
Toolbar toolbar = findViewById(R.id.toolbar);
// 加载知乎菜单
toolbar.inflateMenu(R.menu.menu_zhihu);
// 设置导航图标
toolbar.setNavigationIcon(R.mipmap/ic_drawer);
// 设置标题及颜色
toolbar.setTitle("知乎");
toolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
}
}
5. 进阶优化:沉浸式状态栏
在Android 4.4+中,可结合Translucent System Bar特性,让Toolbar延伸至状态栏,实现知乎的沉浸式效果:
- 在
values-v19/styles.xml中添加:
<style name="AppTheme.Zhihu" parent="AppTheme">
<item name="android:windowTranslucentStatus">true</item>
</style>
- 给Toolbar添加顶部内边距,避免内容被状态栏遮挡:
<androidx.appcompat.widget.Toolbar
...
android:paddingTop="@dimen/status_bar_height"/>
总结
- 核心优势:Toolbar相比ActionBar更灵活,支持自定义位置、样式和控件,是Android导航栏的首选方案;
- 关键避坑:使用兼容版Toolbar时,XML属性需通过自定义命名空间(
xmlns:toolbar)设置,避免属性失效;修改Action Menu文字颜色需用textColorPrimary替代actionMenuTextColor; - 实战要点:使用前需隐藏系统默认ActionBar,可通过
supportRequestWindowFeature或NoActionBar主题实现;自定义Theme可修改溢出菜单图标、文字样式等细节。

浙公网安备 33010602011771号