1. 程式人生 > >安卓專案實戰之:ToolBar的使用介紹

安卓專案實戰之: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實現側滑動畫效果,時間關係後續再來完善。