Android Toolbar的用法

童思宇發表於2018-02-09

Toolbar的強大之處在於,它不僅繼承了ActionBar的所有功能,而且靈活性很高,可以配合其他控制元件來完成一些Material Design的效果,下面來具體的看一下.

首先你要知道,任何一個新建的專案,預設都是會顯示ActionBar的,這個想必你已經見識過太多次了,那麼這個ActionBar到底是從哪裡來的呢?其實這是根據專案中指定的主題來顯示的,開啟AndroidManifest.xml檔案看一下,如圖:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    ...
</application>

可以看到,這裡使用android.theme屬性指定了一個AppTheme的主題,那麼這個AppTheme又是在哪裡定義的呢?開啟res/values/styles.xml檔案,程式碼如下:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

這裡定義了一個叫AppTheme的主題,然後指定它的parent主題是Theme.APPCompat.Light.DarkActionBar,這個DarkActionBar是一個深色的ActionBar主題,我們之前所有的專案中自帶的ActionBar就是因為指定了這個主題才出現的,

而現在我們準備使用Toolbar來代替ActionBar,因此需要指定一個不帶ActionBar的主題,通常有Theme.APPCompat.NoActionBar和Theme.APPCompat.Light.NoActionBar這兩種主圖可選,其中Theme.APPCompat.NoActionBar表示深色主題,它會將介面的主體顏色設成深色,陪襯顏色設成淡色,而Theme.APPCompat.Light.NoActionBar表示淡色主體,它會將介面的主體顏色設成淡色,陪襯顏色設成深色,這裡我選擇用淡色主題了,如下所示:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

然後觀察一下AppTheme中的屬性重寫,這裡重寫了colorPrimary,colorPrimaryDark和colorAccent這3個屬性的顏色,除了這3個屬性之外,我們還可以通過textColorPrimary,windowBackground和navigationBarColor等屬性來控制更多位置的顏色,不過唯獨colorAccent這個屬性比較難理解,它不只是用來指定這樣一個按鈕的顏色,而是更多表達了一個強調的意思,比如一些控制元件的選中狀態也會使用colorAccent的顏色.

現在我們已經將ActionBar隱藏起來了,那麼接下來看一看如何使用Toolbar來代替ActionBar,activity_main.xml中的程式碼,如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.toolbartest.MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

</android.support.constraint.ConstraintLayout>

接下來是MainActivity.Java中的程式碼,如下:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    }
}

首先通過findViewById()得到Toolbar的例項,然後呼叫setSupportActionBar()方法將Toolbar的例項傳入,這樣我們就做到即使用了Toolbar,又讓它的外觀與功能都能和ActionBar一致了.

現在執行一下程式,如圖:

這個標題欄我們再熟悉不過了,雖然看上去和之前的標題沒什麼兩樣,但其實它已經是Toolbar而不是ActionBar了,因此它現在也具備了實現Material Design效果的能力.

現在我們再看一下Toolbar比較常用的功能,比如修改標題上顯示的文字內容,這段文字內容是在AndroidManifest,xml中指定的,如下:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity"
        android:label="Fruits">
        ...
    </activity>
</application>

這裡給activity增加了一個android:label屬性,用於指定在Toolbar中顯示的文字內容,如果沒有指定的話,會預設使用application中指定的label內容,也就是我們的應用名稱.

不過只有一個標題的Toolbar看起來太單調了,我們還可以再新增一些action按鈕來讓Toolbar更加豐富一些,這裡我提前準備了幾張圖片來作為按鈕的圖示,將它們放在了drawable目錄下,現在右擊res目錄-->New-->Directory,建立一個menu資料夾,然後右擊menu資料夾-->New-->Menu resource file,建立一個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">

    <item
        android:id="@+id/backup"
        android:icon="@drawable/ic_backup"
        android:title="Backup"
        app:showAsAction="always" />

    <item
        android:id="@+id/delete"
        android:icon="@drawable/ic_delete"
        android:title="Delete"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/settings"
        android:icon="@drawable/ic_settings"
        android:title="Settings"
        app:showAsAction="never" />

</menu>

可以看到,我們通過<item>標籤來定義action按鈕,android:id用於指定按鈕的id,android:icon用於指定按鈕的圖片,android:title用於指定按鈕的文字.

接著使用app:showAsAction來指定按鈕的顯示位置,之所以這裡再次使用了app名稱空間,同樣是為了能夠相容低版本的系統,showAsAction主要有以下幾種值可選,always表示永遠顯示在Toolbar中,如果螢幕空間不夠則不顯示,ifRoom表示螢幕空間足夠的情況下顯示在Toolbar中,不夠的話就顯示在選單當中,never則表示永遠顯示在選單當中,注意,Toolbar中的action按鈕只會顯示圖示,選單中的action按鈕只會顯示文字.

接下來修改MainActivity中的程式碼,如下:

public class MainActivity extends AppCompatActivity {

    ...
    
    public boolean onCreateOptionsMenu(Menu menu){
        getMenuInflater().inflate(R.menu.toolbar,menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.backup:
                Toast.makeText(this,"You clicked Backup",Toast.LENGTH_SHORT).show();
                break;
            case R.id.delete:
                Toast.makeText(this,"You clicked Delete",Toast.LENGTH_SHORT).show();
                break;
            case R.id.settings:
                Toast.makeText(this,"You clicked Settings",Toast.LENGTH_SHORT).show();
                break;
                default:
                    break;
        }
        return true;
    }
}

很簡單,我們在onCreateOptionMenu()方法中載入了toolbar.xml這個選單檔案,然後在onOptionsItemSelected()方法中處理各個按鈕的點選事件,現在重新執行一下,效果如圖:

可以看到,Toolbar上面現在顯示了兩個action按鈕,這是因為Backup按鈕指定的顯示位置是always,Delete按鈕指定的顯示位置是ifRoom,而現在螢幕空間很充足,因此兩個按鈕都會顯示在Toolbar中,另外一個Settings按鈕由於指定的顯示位置是never,所以不會顯示在Toolbar中,點選最右邊的選單按鈕來展示選單項,你就能找到Settings了.

相關文章