安卓專案實戰之:ToolBar的使用介紹
ToolBar簡介
Toolbar是谷歌在2014年Google IO 大會上推出的一套全新的設計規範Material Design中的控制元件之一,主要是用來在android 5.0之後代替Android傳統的標題欄ActionBar的,引入在android-support-v7相容包下,使用ToolBar能實現和ActionBar一樣的效果,並且ToolBar繼承自ViewGroup,使用起來也是更加的靈活。
ToolBar的組成如下圖:
對應的佈局檔案屬性設定如下:
<android.support.v7.widget.Toolbar
android: id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
app:logo="@mipmap/ic_launcher"
app:title="標題"
app:titleTextColor="#fff"
app:subtitle="副標題"
app:subtitleTextColor= "#fff"
app:navigationIcon="@drawable/ic_menu"
app:popupTheme="@style/toolBar_pop_item"
>
對導航圖示navigationIcon設定點選監聽:
mToolbar=findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);//利用Toolbar代替ActionBar
//設定導航Button點選事件
mToolbar.setNavigationOnClickListener(new View.OnClickListener () {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"點選導航欄",Toast.LENGTH_SHORT).show();
}
});
如果你添加了 setSupportActionBar(toolbar); 這行程式碼,那麼 toolbar.setNavigationOnClickListener監聽方法,要放到其後面,否則點選事件,監聽不到的。如果你用不到ActionBar的一些特性的話,建議setSupportActionBar(toolbar); 這行程式碼不用添加了。
關於選單及自定義View的使用會在下面詳細介紹。
為什麼會有ToolBar?
傳統的ActionBar在每次Android SDK版本更新時都會做一些改變,所以在不同的手機上往往會展示出不一樣的效果,導致很嚴重的碎片化問題,GooGle官方為了解決這種碎片化問題在某次更新android-support-v7相容包時引入了ToolBar,用來替代ActionBar,以達到不同版本展示效果的高度一致性。
為什麼要使用ToolBar?
1,首先上面也說了如果要實現標題欄,優先考慮使用ToolBar,可以有效的解決相容性問題。
2,有很多人有這樣的疑問,我自己寫一個RelativeLayout或者其他什麼佈局都能實現標題欄,為什麼非要用Toolbar呢?當然了首先它是GooGle官方推薦的標題控制元件,其次是使用ToolBar和其他MD設計風格的控制元件組合使用,能實現一些比較炫的效果,比如Toolbar+NestScrollView,Toolbar+DrawerLayout + NavigationView等等;
ToolBar在實際專案中的使用
1,因為ToolBar位於V7包下,所以首先我們要確保應用引入了V7包,使用V7包下的ToolBar控制元件這樣就可以相容到5.0以下的版本。
2,設定專案的主題為NoActionBar。
3,在佈局檔案中使用:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:background="@color/colorAccent"
android:layout_width="match_parent"
app:navigationIcon="@drawable/ic_arrow_back_white"
app:title="我是ToolBar"
app:titleTextColor="#fff"
android:layout_height="?attr/actionBarSize">
</android.support.v7.widget.Toolbar>
</RelativeLayout>
上面ToolBar的高度可以給個固定值也可以使用?attr/actionBarSize指定為ActionBar的高度一致。
Activity中程式碼也很簡單,初始化控制元件Toolbar,然後設定導航圖示的點選事件監聽,需要注意的是如果添加了 setSupportActionBar(toolbar); 這行程式碼,那麼 toolbar.setNavigationOnClickListener監聽方法,要放到其後面,否則點選事件,監聽不到的,或者如果使用不到ActionBar的特性的話,這行程式碼我們完全可以不新增照樣可以監聽到導航按鈕點選監聽。
最終效果如下圖:
設定選單選項
1,首先在res目錄下建立menu資料夾,然後定義一個toolbar_menu.xml檔案,用於toolbar標題欄中各種action按鈕的展示:
<?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"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<!--orderInCategory選單項的優先順序,也就是順序,只能設定正整數,數值越大選單項越靠前-->
<item
android:id="@+id/item1"
android:orderInCategory="100"
android:title="搜尋"
android:icon="@drawable/icon_search"
app:showAsAction="ifRoom"
/>
<item
android:id="@+id/item2"
android:orderInCategory="100"
android:title="通知"
android:icon="@drawable/icon_notify"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/item3"
android:orderInCategory="100"
android:title="設定"
app:showAsAction="never"/>
<item
android:id="@+id/item4"
android:orderInCategory="100"
android:title="關於"
app:showAsAction="never"/>
</menu>
可以看出選單中每個Item主要設定四個屬性:id(用於監聽區分),title(選單名稱),icon(圖示),以及showAsAction(控制item在標題欄上的展示形式),預設Toolbar中顯示的選單項只會顯示圖示,設定的title不顯示,但是我們長按該圖示會發現title會顯示在圖示下方,另外溢位選單中也只會顯示選單的title,不顯示圖示。
showAsAction屬性我們主要關心如下三個取值:
1,always:表示永遠顯示在Toolbar中,如果螢幕空間不夠則不顯示。
2,ifRoom:如果toolbar上還有空間的話就會顯示優先順序高的選單項在toolbar上,否則將剩下的顯示在溢位選單中 。
3,never:表示永遠不顯示在Toolbar中,而是一直顯示在溢位選單中。
2,在程式碼中關聯Toolbar和menu選單,並設定選單的點選事件監聽:
// 關聯toolbar和menu,只需這一句程式碼選單就可以正常顯示了
toolBar.inflateMenu(R.menu.toolbar_menu);
// 手動設定溢位選單項的圖示
toolBar.setOverflowIcon(getResources().getDrawable(R.drawable.ic_menu_over_flow));
// 設定選單點選事件監聽
toolBar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case R.id.item1:
Toast.makeText(ToolbarActivity.this, "選單項1", Toast.LENGTH_SHORT).show();
break;
case R.id.item2:
Toast.makeText(ToolbarActivity.this, "選單項2", Toast.LENGTH_SHORT).show();
break;
case R.id.item3:
Toast.makeText(ToolbarActivity.this, "選單項3", Toast.LENGTH_SHORT).show();
break;
case R.id.item4:
Toast.makeText(ToolbarActivity.this, "選單項4", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return false;
}
});
經過以上步驟後選單就新增成功了,最終效果如下圖:
因為在menu配置檔案中我們設定了最後兩個選單項的showAsAction為never,所以預設會在標題欄的最右側顯示一個溢位選單選項,該溢位選單項的圖示預設為灰色的豎排顯示的三個小圓點,我們可以更改該圖示,只要新增如下這句程式碼即可:
toolBar.setOverflowIcon(getResources().getDrawable(R.drawable.ic_menu_over_flow));
溢位選單選項用來展示showAsAction屬性為never和空間不足以展示的選單項,當然瞭如果沒有未被展示的item,這裡就不會出現這個圖示,然後我們點選溢位圖示,系統預設的彈出樣式是這樣的:
首先我們發現溢位選單彈出框中預設只顯示選單的title,不顯示圖示,如果我們想要溢位選單的彈出框中除了能顯示title外,還想顯示圖示,那麼也是可以的,這裡提供兩種方案,具體請檢視部落格:https://blog.csdn.net/shangming150/article/details/77914110
其次我們可以看到預設的溢位選單的彈出框樣式非常醜,並且遮擋住了Toolbar標題欄,但是沒關係,我們可以通過在佈局檔案中指定app:popupTheme="@style/menu_bg"屬性來指定一個自定義的樣式,至於這個樣式具體能定義哪些內容,下面給出一個示例:
<!--自定義toolbar選單樣式-->
<style name="toolbarMenuStyle" parent="@style/Widget.AppCompat.PopupMenu.Overflow">
<!-- 是否覆蓋錨點,預設為true,即蓋住Toolbar -->
<item name="overlapAnchor">false</item>
<!-- 彈出層背景顏色 -->
<item name="android:popupBackground">@color/material_deep_teal_500</item>
<!-- 彈出層垂直方向上的偏移,負值會覆蓋toolbar -->
<item name="android:dropDownVerticalOffset">5dp</item>
<!-- 彈出層水平方向上的偏移,即距離螢幕左邊的距離,負值會導致右邊出現空隙 -->
<item name="android:dropDownHorizontalOffset">-2dp</item>
<!--文字顏色-->
<item name="android:textColor">@color/white</item>
</style>
定義好樣式後需要在app的主題中引用該樣式,才能改變溢位框內的文字顏色,如下:
<!-- Base application theme. -->
<style name="AppTheme" parent="Base.AppTheme">
<!--指定toolbar彈出選單樣式-->
<item name="actionOverflowMenuStyle">@style/toolbarMenuStyle</item>
</style>
最後在toolbar中引用:
<android.support.v7.widget.Toolbar
android:background="@color/material_deep_teal_500"
android:id= "@+id/toolbar"
android:layout_width="match_parent"
app:popupTheme="@style/toolbarMenuStyle"
android:layout_height="?attr/actionBarSize">
</android.support.v7.widget.Toolbar>
這樣溢位選單的彈出框樣式我們就修改完成了,具體再根據專案需求作相應的更改。
標題居中問題和自定義Toolbar
如果專案要求標題欄上的標題居中顯示,通過檢視檢視api我們發現toolbar沒有提供標題居中的方法,僅僅是提供了使其距左右,上下邊距大小的方法。
不過不用擔心,之前文中提到過Toolbar是一個ViewGroup,如果需要新增自定義View,只需要在Toolbar裡面增加其子ViewGroup或者子View,然後設定居中即可。
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="center_vertical"
>
<ImageView
android:id="@+id/iv_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_back"
android:layout_centerVertical="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#fff"
android:text="標題"
android:textSize="18sp"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
</android.support.v7.widget.Toolbar>
上面的佈局檔案中沒有使用預設的導航圖示而是自定義了ImageView,如果想使用預設的導航圖示也是可以的,佈局修改如下即可:
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorAccent">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="標題"
android:textColor="@color/white"
android:textSize="22sp" />
</android.support.v7.widget.Toolbar>
注意此時 TextView 控制元件的寬和高都是自適應大小,java 程式碼中此行程式碼setSupportActionBar(toolbar);就不要添加了,否則就會顯示不正常。
除非用到ActionBar的特性不然不推薦新增這行程式碼。
關於Toolbar就先介紹這麼多,關於Toolbar和DrawerLyout實現側滑動畫效果,時間關係後續再來完善。