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:navigationIconandroid:title等属性设置后无效果。
原因:兼容版Toolbar的自定义属性不在默认Android SDK命名空间中,需单独声明。
解决方案

  1. 在布局根节点添加自定义命名空间:xmlns:toolbar="http://schemas.android.com/apk/res-auto"
  2. android:xxx替换为toolbar:xxx(如toolbar:titletoolbar:logo

坑2:Action Menu文字颜色修改无效

问题现象:设置actionMenuTextColor后,菜单文字颜色未变化。
解决方案

  1. 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>
  1. 在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延伸至状态栏,实现知乎的沉浸式效果:

  1. values-v19/styles.xml中添加:
<style name="AppTheme.Zhihu" parent="AppTheme">
    <item name="android:windowTranslucentStatus">true</item>
</style>
  1. 给Toolbar添加顶部内边距,避免内容被状态栏遮挡:
<androidx.appcompat.widget.Toolbar
    ...
    android:paddingTop="@dimen/status_bar_height"/>

总结

  1. 核心优势:Toolbar相比ActionBar更灵活,支持自定义位置、样式和控件,是Android导航栏的首选方案;
  2. 关键避坑:使用兼容版Toolbar时,XML属性需通过自定义命名空间(xmlns:toolbar)设置,避免属性失效;修改Action Menu文字颜色需用textColorPrimary替代actionMenuTextColor
  3. 实战要点:使用前需隐藏系统默认ActionBar,可通过supportRequestWindowFeature或NoActionBar主题实现;自定义Theme可修改溢出菜单图标、文字样式等细节。
posted @ 2016-12-30 18:04  灰色飘零  阅读(4517)  评论(0)    收藏  举报