讓構建標題欄變得更加簡單, Toolbar 的增強之旅
前言
鄰近國慶, 給大家帶來一些乾貨, 希望能夠幫助大家提高開發效率
2018 年的 GDD 大會, Google 再次力薦了全新的 Material Design 元件, 筆者深深為之著迷(哈哈, 老臉一紅), Toolbar 這個元件, 相信大家都接觸過, 它幾乎已經取代了之前 ActionBar 的地位, 不過單憑藉 Google 提供的 Toolbar 實在難以勝任開發過程中多變的 UI 風格, 藉此契機, 將以前自定義的CommonToolbar 的元件進行了再次增強, 以適用絕大多數的業務場景
接下來就通過幾個場景來介紹這款新的元件
場景一
場景描述

場景一.png
- 構建一個左邊有一個返回按鈕的標題欄
- 標題文字處於中間狀態
通過 SToolbar 的實現方式
方式一:
在 xml 檔案中, 使用自定義屬性
<com.sharry.libtoolbar.SToolbar android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary" app:backIcon="@drawable/icon_back" app:titleGravity="Center" app:titleText="Sharry" app:titleTextSize="18dp" />
- backIcon: 返回按鈕的資原始檔
- titleGravity: 標題的位置(預設居中)
- textText: 標題文字
- titleTextSize: 標題文字的大小
- titleTextColor: 標題文字的顏色
方式二:
使用程式碼構建, 呼叫使用 SToolbar.Builder 的方式來構建一個 Toolbar
SToolbar.Builder(this) .setStatusBarStyle(Style.TRANSPARENT) .setBackgroundColorRes(R.color.colorPrimary) .setTitleGravity(Gravity.CENTER_HORIZONTAL) .setTitleText("Sharry") .addBackIcon(R.drawable.icon_back) .apply()
- apply()
- 最終呼叫 apply 會構建一個 SToolbar 的例項物件,
- 並且將它新增到 com.android.internal.R.id.content 這個 ContentParent 中
- 關於這個資原始檔這裡就不過多介紹了( ofollow,noindex">這裡有相關知識點的介紹 )
- 並且會將我們 setContentView 中設定的佈局, 自動的移動到 Toolbar 的下方
嗯, 你能想到的騷操作, 這裡都做了, 徹底解放你的雙手, 如果你想獲取一個物件, 而且不想讓他插入到佈局檔案中, 可以呼叫 .build() 方式即可
SToolbar.Builder(this) .//... .build()
場景二
場景描述

場景二.png
- 標題
- 文字大小為 20 dp
- 文字處於中間狀態
- 左邊有一個返回按鈕
- 選單
- 左邊有一個文字選單
- 右邊有一個文字選單
- 右邊有一個圖片選單
- 文字選單的文字大小為 13dp
- 每個選單之間的間距為 10dp
可見這個場景就複雜的多了
方式一
即使是這樣複雜的文字, 依舊可以通過 xml 中提供的屬性快捷構建
<com.sharry.libtoolbar.SToolbar android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary" app:backIcon="@drawable/icon_back" app:menuLeftText="left_menu" app:menuRightIcon="@drawable/icon_right" app:menuRightText="right_menu" app:menuTextColor="@android:color/white" app:menuTextSize="13dp" app:subItemInterval="10dp" app:titleGravity="Center" app:titleText="Sharry" app:titleTextColor="@android:color/white" app:titleTextSize="18dp" />
- menuLeftText: 左部選單文字
- menuRightText: 右部選單文字
- menuTextSize: 選單文字的大小
- subItemInterval: 每個一個子 Item 之間的間隔
方式二
使用程式碼構建
SToolbar.Builder(this) .setStatusBarStyle(Style.TRANSPARENT) .setBackgroundColorRes(R.color.colorPrimary) // 設定間隔 .setSubItemInterval(10) // 設定Gravity .setTitleGravity(Gravity.CENTER_HORIZONTAL) // 設定標題文字 .setTitleText("Sharry", 18) .addBackIcon(R.drawable.icon_back) // 新增左部的選單文字 .addLeftMenuText( TextViewOptions.Builder() .setText("left") .setListener { showMsg("U click left text") } .build() ) // 新增右邊的選單文字 .addRightMenuText( TextViewOptions.Builder() .setText("right") .setListener { showMsg("U click right text") } .build() ) // 新增右邊的選單圖片 .addRightMenuImage( ImageViewOptions.Builder() .setDrawableResId(R.drawable.icon_right) .setListener { showMsg("U click right image") } .build() ) .apply()
可以看到關於選單的構建, 可以通過新增一個 Options 來構建
- SToolbar 提供了三種 Options
- TextViewOptions
- 傳入這個 Options 會自動建立 TextView 並且新增進指定的選單中
- ImageViewOptions
- 傳入這個 Options 會自動建立 ImageView 並且新增到指定的選單中
- ViewOptions
- 這個 Options 不能夠單獨使用, 要配合 View 去使用
- 說道配合 View, 相信大家應該能夠感受到一些貓膩了, 好的這個到場景三種敘述
- TextViewOptions
- 通過 Options 你可以方便地訂製 View 的各種屬性, 可以精確的定位 view 的 padding 來控制邊距
兩種方式的執行效果圖

效果對比.png
這樣子能夠滿足你的需求嗎? 彆著急, 且看看場景三
場景三
場景描述

場景三.png
- 沉浸式狀態列
- 左邊有個返回按鈕
- 左邊有個文字
- 右邊有個選中框
這樣子複雜的場景? 確定用 SToolbar 能夠實現? 不巧, 還真能
實現方式
- 在 xml 中定義基本的簡單屬性
<com.sharry.libtoolbar.SToolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" app:statusBarStyle="Transparent" app:backIcon="@drawable/icon_back" app:subItemInterval="10dp" app:titleGravity="Left" app:titleTextSize="18dp" />
- statusBarStyle: 這個屬性, 用於控制狀態列
- Transparent: 全透明
- Translucent: 半透明
- Hide: 隱藏狀態列
- Default: 預設狀態
- 其他的屬性在上面的場景中已經介紹過, 這裡不再贅述
- 在程式碼中定義自定義的 Menu
protected void initTitle() { SToolbar toolbar = findViewById(R.id.toolbar); // 1. 建立自定義 View 的屬性 mCheckIndicator = new CheckedIndicatorView(this); // 2. 將這個自定義 View 通過 addRightMenuView 新增到 Toolbar 中 toolbar.addRightMenuView( mCheckIndicator, ViewOptions.Builder() .setVisibility(View.INVISIBLE) .setWidthExcludePadding(dp2px(this, 25)) .setHeightExcludePadding(dp2px(this, 25)) .setPaddingRight(dp2px(this, 10)) .setListener(new View.OnClickListener() { @Override public void onClick(View v) { mPresenter.handleToolbarCheckedIndicatorClick(mCheckIndicator.isChecked()); } }) .build() ); }
這裡就可以看到
- 我們傳入了一個自定義 View
- 構建了一個 ViewOptions, 通過 Builder 設定的屬性最終都會作用到這個 View 上
總結
相信通過上面幾個場景的介紹, 大家對 SToolbar 在使用上, 有了一定程度的瞭解, 其實每個位置上的 View, 都可以通過這種方式去實現, 這樣子我相信應該可以滿足開發過程中絕大多數的需求了
你可以通過 Options 調整各個位置的 View, 也可以在各個位置上新增自定義 View, 比如構造出下面這樣子的 Title

想了解更多請移步到下方的 Github 檢視原始碼