Toolbar使用詳解

Toobar與ActionBar

從Android3.0(API level 11)開始,所有使用默認主題的activity都自帶一個ActionBar,但是隨著Android版本的迭代,ActionBar的特性不斷增加,從而導致了在不同Android系統的設備上,ActionBar的顯示不一致。

從Android5.0(API level 21)開始,引進了Toolbar,它包含了ActionBar最近添加的大多數特性,同時添加到了支持庫中,使得在低版本設備上也可以使用Toolbar。

Toolbar與ActionBar的區別:

  • ToolBar就是一個View,跟其它View一樣包含在布局中。
  • 像常規View一樣,Toolbar很容易來放置、實現動畫以及控制。
  • 一個Activity中可以有多個Toolbar。

Toolbar是簡單使用

  1. 在應用的build.gradle中添加v7 appcompat支持庫。
com.android.support:appcompat-v7:24.1.1
  1. 讓Activity繼承自AppCompatActivity。
public class MyActivity extends AppCompatActivity {
    // ...
} 
  1. 在AndroidManifest.xml文件中,設置<application>元素使用appcompat中的某個NoActionBar主題,從而來去除使用ActionBar來提供操作欄。
<application
        android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
  1. 在activity的布局中添加Toolbar。
<android.support.v7.widget.Toolbar
   android:id="@+id/my_toolbar"
   android:layout_width="match_parent"
   android:layout_height="?attr/actionBarSize"
   android:background="?attr/colorPrimary"
   android:elevation="4dp"
   android:theme="@style/ThemeOverlay.AppCompat.ActionBar"  
   app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
  1. 在activity的onCreate()方法中,調用setSupportActionBar()方法,并傳入toolbar,這樣就會將toolbar設置為activity的操作欄了。
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my);
    Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
    setSupportActionBar(toolbar);
}

運行之后,效果圖如下:

Toolbar簡單使用.png

至此,activity有了一個基本的操作欄。可以通過獲取的toolbar的引用,調用相關API來實現更多操作,例如隱藏或顯示操作欄。

Toolbar元素

上面的效果圖中,只顯示了App的名稱,但是Toolbar可以包含以下元素:

  • 導航按鈕
  • 應用的Logo
  • 標題和子標題
  • 若干個自定義View
  • 動作菜單

好的,接下來我們就讓它們全部顯示出來。

  1. 顯示導航按鈕、應用的Logo、標題和子標題。
// 顯示應用的Logo
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setLogo(R.mipmap.ic_launcher);

// 顯示標題和子標題  
getSupportActionBar().setDisplayShowTitleEnabled(true);
toolbar.setTitle("ToolbarDemo");
toolbar.setSubtitle("the detail of toolbar");
// 顯示導航按鈕
toolbar.setNavigationIcon(R.drawable.icon_back);
  1. 顯示動作菜單。
    首先在res/menu目錄下的xml文件中定義的,要添加幾個動作,則在<menu>節點下添加幾個item。
<?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/toolbar_action1"
        android:icon="@drawable/icon_weibo_timeline_mine"
        android:title="Action"
        app:showAsAction="always"/>

    <item
        android:id="@+id/toolbar_action1"
        android:icon="@drawable/icon_weibo_timeline_mine"
        android:title="Action"
        app:showAsAction="never"/>

  </menu>

item的icon和title屬性顧名思義,而app:showAsAction屬性則是用來指定這個動作是放置在操作欄上,還是溢出菜單中。當它的值設置為”ifRomom”時,如果操作欄有空間放置,則放置在操作欄上,否則放置到溢出菜單中。當它的值設置為”always”,這個動作將總是放置在操作欄上。當它的值設置為”never”,這個動作將總是放置在溢出菜單中。

之后重寫activity的onCreateOptionsMenu()方法,設置顯示的menu資源:

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

當點擊了按鈕,可以通過重寫activity的onOptionsItemSelected()方法來進行處理:

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
      switch (item.getItemId()) {
          case R.id.toolbar_action1:
              // do something
              return true;
          default:
              // If we got here, the user's action was not recognized.
              // Invoke the superclass to handle it.
              return super.onOptionsItemSelected(item);

      }
  }
  1. 顯示自定義View

因為Toolbar是ViewGroup的子類,因此可以向其內部添加View進行顯示。這里我們簡單的添加一個TextView顯示一個文本。

<android.support.v7.widget.Toolbar
  android:id="@+id/toolbar"
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  android:background="?attr/colorPrimary"
  android:elevation="4dp"
  android:theme="@style/ToolbarTheme"
  app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
  app:titleTextAppearance="@style/Toolbar.TitleText">

  <TextView
      android:id="@+id/toolbar_title"
      style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="center"
      android:text="自定義"
      android:textSize="21sp"/>

</android.support.v7.widget.Toolbar>

好了,所有的元素都添加到了Toolbar上,運行效果圖如下:

Toolbar元素

Toolber復用

應用中有很多界面,每個Activity一般都需要操作欄,且大多數activity的操作欄的元素是一致的,那每個布局文件里面都寫這么多資源文件是累贅的。因此可以對Toolbar進行復用,使得布局文件看起來更精煉,更改Toolbar整體效果,如背景之類的可以更方便。

首先,在布局文件toolbar.xml中定義Toolbar。

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:contentInsetLeft="0dp"
    android:contentInsetStart="0dp"
    android:elevation="4dp"
    android:theme="@style/ToolbarTheme"
    app:navigationIcon="@drawable/icon_back"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:titleTextAppearance="@style/Toolbar.TitleText">

    <!--  any custom view -->

</android.support.v7.widget.Toolbar>

之后,在需要添加Toolbar的地方引入這個布局資源。

<include
  layout="@layout/toolbar"/>

最后,在BaseActivity(一般app都會有)中的onCreate()方法設置Toolbar。注意,這個時候Activity不再繼承AppCompatActivity,而是繼承BaseActivity,而BaseActivity繼承AppCompatActivity。BaseActivity部分代碼如下:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    if (toolbar != null) {
        setSupportActionBar(toolbar);

        mToolbarHelper = new ToolbarHelper(toolbar);

        hanldeToolbar(mToolbarHelper);
    }
}

protected void hanldeToolbar(ToolbarHelper toolbarHelper) {}

public static class ToolbarHelper {

    private Toolbar mToolbar;

    public ToolbarHelper(Toolbar toolbar) {
        this.mToolbar = toolbar;
    }

    public Toolbar getToolbar() {
        return mToolbar;
    }

    public void setTitle(String title) {
        TextView titleTV = (TextView) mToolbar.findViewById(R.id.toolbar_title);
        titleTV.setText(title);
    }
}

代碼中首先獲取到Toolbar將其設置為操作欄,之后創建了一個ToolbarHelper對象,ToobarHelper主要是封裝了下Toolbar,并提供操作自定義View的方法。然后調用hanldeToolbar()方法,子Activity通過重寫這個方法,可以對Toolbar進行定制操作。

在真實項目中應用Toolbar

在上面我們看到了顯示所有Toolbar元素的效果圖,肯定會說,這跟我們產品設計的不一樣,跟應用中所需要的不一樣。一般我們應用中大多是這樣的:

常用Toolbar.png

觀察下,首先左邊是一個返回按鈕,中間是標題,有可能右邊是文本或者按鈕來提供分享、編輯之類的操作。接下來,我們來看看如何實現。

  1. 實現返回按鈕,在之前我們設置過顯示導航按鈕、logo、標題及子標題。現在將導航按鈕作為返回按鈕,設置為UI提供的圖標,而logo和標題類的設置不顯示就可以了。

接下來就是設置事件監聽了,還記得添加按鈕時的事件處理么?一樣的都是在onOptionsItemSelected()進行處理,它的id是android.R.id.home:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
  switch (item.getItemId()) {
      case android.R.id.home:
          FragmentManager fm = getSupportFragmentManager();
          if (fm != null && fm.getBackStackEntryCount() > 0) {
              fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
          } else {
              finish();
          }
          return true;
      default:
          return super.onOptionsItemSelected(item);
  }
}
  1. 實現中間標題的顯示。在上一步我們禁用了Toolbar原本顯示在左邊的標題,中間的標題我們可以通過向Toolbar中添加TextView實現,與之前顯示Toolbar上所有元素中的自定義View是一樣的。對于更改標題,則通過上面Toolbar復用所提到的ToolbarHelper進行操作。
  2. 右邊的文本及圖標顯示。這個可以使用Toolbar本身的menu(前面已經介紹過),也可以將其作為自定義View。

總之,這三部分(左邊+中間+右邊)實現方式大致如此,根據你的項目,合理地進行安排。

最后,附上源碼地址:
https://github.com/FILWAndroid/DevJourney

關于源碼:

  1. 不只是本文涉及的代碼,會包含很多知識點的代碼,應該都會在我的簡書中進行介紹。
  2. 有可能代碼與本文中所貼出來的有差異,但應該都是我覺得更好的方式吧。
  3. 歡迎大家對我進行批評教育。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容