Toolbar
是在 Android 5.0 開始推出的一個 Material Design 風格的導航控件,用來代替以之前的ActionBar
。盡管Google誠意滿滿,使用Toolbar
依然是一部踩坑填坑的血淚史。
對于Toolbar
Google給開發者留了很多可定制修改的余地。官方文檔
- 設置導航按鍵
- 設置程序Logo
- 設置主/副標題
- 設置一個或多個自定義控件
- 支持acition menu
1. Toolbar的引入
Toolbar
用來替代ActionBar
,所以Activity的Theme
設置成NoActionBar
的例如Theme.AppCompat.Light.NoActionBar
或者在代碼中去掉導航欄在onCreate()
中添加supportRequestWindowFeature(Window.FEATURE_NO_TITLE)
1.1 添加兼容包依賴
Toolbar
是向下兼容的,所以使用時添加support
依賴包compile 'com.android.support:appcompat-v7:23.1.1'
1.2 在布局文件中引入Toolbar
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:navigationIcon="@drawable/ic_drawer_home"http://導航圖標
app:logo="@mipmap/ic_launcher"http://程序logo
app:title="Title"http://主標題
app:subtitle="SubTitle"http://副標題>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="custom view"
android:textColor="#fff"
android:textSize="18sp" />
</android.support.v7.widget.Toolbar>
1.3 在代碼中設置Toolbar
替代ActionBar
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_toolbar);
Toolbar toolbar= (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);//Toolbar 代替ActionBar
}
程序預覽
2. 標題字體樣式的自定義
簡單的引入了
Toolbar
,但這并不能滿足我們的開發要求。標題的字體樣式我們總得按照設計稿來吧。
2.1 修改標題字體顏色
app:titleTextColor="@color/colorAccent"http://修改主標題字體顏色
app:subtitleTextColor="@color/colorAccent"http://修改副標題字體顏色
2.2 修改標題字體大小
修改字體大小就比較坑了,我沒找到設置字體大小的直接屬性??赡?code>Toolbar的設計中會自動設置標題的字體大小為一個合適的值。其實用默認的大小基本ok。如果想要修改字體大小可以嘗試下面的方法。
我在樣式文件中定義了需要樣式的父類樣式,所以后面 的樣式都沒寫parent
,他們都自動繼承這個樣式
<!--Toolbar 樣式-->
<style name="Theme.Toolbar" parent="ThemeOverlay.AppCompat.ActionBar">
</style>
2.2.1 在styles.xml
定義標題的字體樣式
<!--Toolbar 主標題的字體和顏色-->
<style name="Theme.Toolbar.Title">
<item name="android:textSize">14sp</item>
<item name="android:textColor">@color/colorAccent</item>
</style>
<!--Toolbar 副標題的字體和顏色-->
<style name="Theme.Toolbar.SubTitle">
<item name="android:textSize">12sp</item>
<item name="android:textColor">@color/colorAccent</item>
</style>
2.2.2 在布局文件中使用樣式
app:subtitleTextAppearance="@style/Theme.Toolbar.SubTitle"
app:titleTextAppearance="@style/Theme.Toolbar.Title"
3. Action Menu的添加
由于上面已經通過setSupportActionBar(toolbar)
將Toolbar
設置成了程序的ActionBar
。菜單布局的渲染和菜單按鍵的監聽可以直接在Activity
的回調方法中實現
3.1 創建菜單布局文件
<?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/menu1"
android:icon="@drawable/ic_search"
android:title="menu1"
app:showAsAction="always" />
<item
android:id="@+id/menu2"
android:icon="@drawable/ic_notifications"
android:title="menu2"
app:showAsAction="never" />
</menu>
3.2 加載菜單布局文件
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toobar, menu);
return super.onCreateOptionsMenu(menu);
}
3.3 設置菜單點擊回調監聽
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu1:
Toast.makeText(ToolbarActivity.this, "item1:" + item.getTitle().toString(), Toast.LENGTH_SHORT).show();
break;
case R.id.menu2:
Toast.makeText(ToolbarActivity.this, "item2" + item.getTitle().toString(), Toast.LENGTH_SHORT).show();
break;
}
return super.onOptionsItemSelected(item);
}
4. Action Menu樣式的自定義
如圖預覽所示,這里會有下面幾個問題:
- 顯示更多菜單按鍵由系統生成和其他圖標不符
- 菜單彈窗背景字體樣式等的自定義
- 菜單彈窗中子菜單項圖標沒有顯示(運行到手機也沒顯示)
4.1 顯示更多菜單圖標的替換
4.1.1 在styles.xml樣式文件中定義Toolbar
的樣式
<!--Toolbar 樣式-->
<style name="Theme.Toolbar" parent="ThemeOverlay.AppCompat.ActionBar">
<item name="actionOverflowButtonStyle">@style/Toolbar_action_menu</item>
</style>
<!--更多菜單圖標-->
<style name="Toolbar_action_menu">
<item name="android:src">@drawable/ic_menu_more_overflow</item>
</style>
4.1.2 在布局文件中為Toolbar
指定樣式文件
android:theme="@style/Theme.Toolbar"
4.2 菜單彈窗背景、字體的自定義
4.2.1 在styles.xml樣式文件中定義Toolbar
菜單的樣式
<!--菜單上文字的大小和顏色-->
<style name="Theme.Toolbar.PopMenu">
<item name="android:textSize">18sp</item>
<item name="android:textColor">@color/colorAccent</item>
<item name="android:background">@color/cl_1B2137</item>
</style>
4.1.2 在布局文件中為Toolbar
彈窗菜單指定樣式文件
app:popupTheme="@style/Theme.Toolbar.PopMenu"
4.3 菜單彈窗子菜單圖標不顯示解決方案
4.3.1 添加菜單顯示的方法
//設置菜單選項圖標是否顯示
private void setIconEnable(Menu menu, boolean enable) {
if (menu != null) {
if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
try {
Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, enable);
} catch (Exception e) {
}
}
}
}
4.3.2 在創建菜單的時候設置圖標是否顯示
@Override
public boolean onCreateOptionsMenu(Menu menu) {
setIconEnable(menu, true);
getMenuInflater().inflate(R.menu.toobar, menu);
return super.onCreateOptionsMenu(menu);
}
在手機上運行顯示截圖如下
5. 關于主標題的顯示問題
因為在代碼中通過setSupportActionBar(toolbar);
將Toolbar
設置成了ActionBar
,所以如果沒有沒置Toolbar
的主標題,或者主標題設置為了空app:title=""
,系統會獲取Activity
的lable
字段設置為主標題。如果Activity
的lable
為空則會獲取application
的label
字段設置title
。解決這個問題需要在代碼中添加getSupportActionBar().setDisplayShowTitleEnabled(false);