不要再封装自己的Bar了;
1. 简介
Android 3.0 Android 推了 ActionBar, 本意是想要逐渐改善过去 android 纷乱的界面设计,但ActionBar 使用并不方便,限制了App的开发与设计的弹性,实际使用的也不多了。
Toolbar 是android 5.0的推出的,放在了v7包中作为控件,它是为了取代ActionBar而产生的,意味着官方在某些程度上认为 ActionBar 限制了App开发与设计的弹性,而在 Material Design 也对之做了名称的定义:App bar
2. 基本使用
2.1 定义Style
Style要调整两个地方
- 一是 res/values/styles.xml中
- 二是 res/values-v21/styles.xml中
为了之后设定方便,我们先在 res/values/styles.xml
里增加一个名为 AppTheme.Base
的风格
<style name="AppTheme.Base" parent="Theme.AppCompat"> <item name="windowActionBar">false</item> <item name="android:windowNoTitle">true</item> </style>
|
因为此范例只使用 Toolbar,所以我们要将让原本的 ActionBar 隐藏起来,然后将原本 AppTheme 的 parent 属性 改为上面的AppTheme.Base,代码如下:
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="AppTheme.Base"> </style> <style name="AppTheme.Base" parent="Theme.AppCompat"> <item name="windowActionBar">false</item> <del><item name="android:windowNoTitle">true</item></del> <!-- 使用 API Level 22 編譯的話,要拿掉前綴字 --> <item name="windowNoTitle">true</item> </style> </resources>
|
再来调整Android 5.0的style:/res/values-v21/styles.xml
,也将其 parent 属性改为 AppTheme.Base:
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="AppTheme" parent="AppTheme.Base"> </style> </resources>
|
2.2 界面(Layout)
在 activity_main.xml 里面添加 Toolbar 控件:
<android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_height="?attr/actionBarSize" android:layout_width="match_parent" > </android.support.v7.widget.Toolbar>
|
请记得用 support v7 里的 toolbar,不然然只有 API Level 21 也就是 Android 5.0 以上的版本才能使用。
2.3 代码(Java)
在 MainActivity.java 中加入 Toolbar 的声明:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar);
|
声明后,再将之用 setSupportActionBar 设定,Toolbar即能取代原本的 ActionBar 了
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/colorPrimary" app:navigationIcon="@drawable/ic_back" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:theme="@style/Theme.Toolbar">
<!-- 标题居中 --> <TextView android:id="@+id/toolbar_title" style="@style/Theme.ToolBar.Title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Title" />
</android.support.v7.widget.Toolbar>
|
@drawable/ic_back
<vector android:height="24dp" android:viewportHeight="1024.0" android:viewportWidth="1024.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> <path android:fillColor="#ffffff" android:pathData="M387.8,164.9a22.1,22.1 0,0 0,-0.4 -30.7,20.5 20.5,0 0,0 -29.7,0.4L0,512.9l357.8,378.3c8,8.5 21.3,8.7 29.7,0.3 8.3,-8.3 8.5,-22 0.4,-30.7L60.3,512.9 387.9,164.9z"/> </vector>
|
@style
<!-- Toolbar --> <style name="Theme.Toolbar" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <!-- 修改toolbar中按钮图标的颜色 --> <item name="colorControlNormal">@color/white</item> </style>
<!-- Toolbar Title--> <style name="Theme.ToolBar.Title" parent="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"> <item name="android:textSize">18sp</item> <item name="android:textColor">@android:color/white</item> </style>
<!-- Toolbar 溢出图标颜色 --> <style name="Theme.Toolbar.OverflowMenuTheme" parent="Theme.AppCompat.NoActionBar"> <!-- 设置Menu菜单背景色 --> <item name="android:itemBackground">@android:color/white</item> <!-- 设置Menu菜单字体颜色 --> <item name="android:textColorPrimary">@android:color/black</item> <!-- 设置Menu窗口不覆盖Toolbar视图 --> <item name="overlapAnchor">false</item> </style>
|
3.2 BaseActivity
public abstract class BaseActivity extends RxAppCompatActivity {
// 让5.0之前的系统可以用Vector图标 static { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); }
/** * 沉浸式状态栏和沉浸式导航栏管理,支持Android 4.4 以上 */ private ImmersionBar mImmersionBar; private Toolbar mToolBar; private TextView mToolbarTitle;
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState);
// 修复系统输入法Bug:在15<=API<=23存在内存泄漏 // https://zhuanlan.zhihu.com/p/20828861 IMMLeaks.fixFocusedViewLeak(getApplication());
// 沉浸式状态栏 mImmersionBar = ImmersionBar.with(this); // 解决状态栏与布局顶部重叠解决方案 mImmersionBar.fitsSystemWindows(true) .statusBarColor(R.color.colorPrimary) .navigationBarColor(R.color.colorPrimary) .init(); }
/** * 统一Toolbar:Activity布局内<include layout="@layout/toolbar"/> * 1. 标题 * 标题居中显示 * 默认使用AndroidManifest的android:label属性值 * 可以在onCreate->setContentView之后,调用setToolbarTitle更新Title * 2. Icon * 3. 间距 * @param layoutResID */ @Override public void setContentView(int layoutResID) { super.setContentView(layoutResID); mToolBar = findViewById(R.id.toolbar); if (mToolBar != null) { mToolbarTitle = mToolBar.findViewById(R.id.toolbar_title); setSupportActionBar(mToolBar); ActionBar actionBar = getSupportActionBar(); // 显示返回键 if(actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); } // 隐藏默认标题 if (mToolbarTitle != null && actionBar != null) { actionBar.setDisplayShowTitleEnabled(false); } } }
/** * 统一Toolbar返回按钮处理 * @param item * @return */ @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { finish(); return true; } return super.onOptionsItemSelected(item); }
/** * 覆盖onTitleChanged:让 title 默认显示到 mToolbarTitle,而且不需要暴露 mToolbarTitle 属性 * 1. 默认显示:AndroidManifest的android:label属性值 * 2. 代码设置:直接调用Activity.setTitle()方法动态修改 * @param title * @param color */ @Override protected void onTitleChanged(CharSequence title, int color) { super.onTitleChanged(title, color); if (mToolbarTitle != null) { mToolbarTitle.setText(title); } }
@Override protected void onDestroy() { super.onDestroy(); if (mImmersionBar != null) { mImmersionBar.destroy(); } }
}
|
完整代码
参考项目内 android-library MainActivty
4. 参考
- Android Toolbar,你想知道的都在这里了
- Toolbar作为ActionBar与标题居中-封装
- Android:改变 Toolbar 的文字和溢出图标颜色
- ToolBar随心定制 - 简书:介绍了如何在ToolBar左侧放置Menu等