ToolBar專案封裝使用

weixin_34148340發表於2018-06-16

概述

繼承關係:

java.lang.Object
   ↳	android.view.View
 	   ↳	android.view.ViewGroup
 	 	   ↳	android.widget.Toolbar
複製程式碼

其實toolbar就是一個封裝好的ViewGroup,其主要五大部分對應的子View如下:

//選單,ActionMenuView也是個ViewGroup
private ActionMenuView mMenuView;
//主標題
private TextView mTitleTextView;
//副標題
private TextView mSubtitleTextView;
//導航按鈕
private ImageButton mNavButtonView;
//Logo圖示
private ImageView mLogoView;
複製程式碼

看下圖,比較清晰:

專案封裝

配置theme

為了適配5.0之後安卓的設計,做起statusbar的顏色適配

<style name="AppTheme" parent="Theme.AppCompat.Light.Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimaryDark">@color/main_dark</item>
        <item name="colorPrimary">@color/main</item>
        <item name="colorAccent">@color/strong</item>
        <item name="android:textColorPrimary">@android:color/white</item>
        <item name="android:actionBarSize">@dimen/nav_bar_height</item>
    </style>
複製程式碼

這裡注意下,主題使用的parent是Theme.AppCompat.Light.NoActionBar,當然有些專案中配全域性Theme時候還是用的Theme.AppCompat.Light.DarkActionBar,這時候需要改成沒有ActionBar的主題,這裡可以直接改成Theme.AppCompat.Light.NoActionBar,但是有些專案裡如果想有些地方使用Actionbar有些地方使用Toolbar(當然很少。。)可以這樣配一下即可:

<style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
</style>
複製程式碼

然後在需要使用Toolbar的activity裡給他配上這樣的theme即可:

<activity
        android:name=".ui.activity.MainTabBarActivity"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:launchMode="singleTask"
        android:theme="@style/AppTheme.NoActionBar"
        android:windowSoftInputMode="stateHidden">
</activity>
複製程式碼

關於theme中幾個color欄位的描述看谷歌官方圖,如下:

或者看谷歌文件(自備梯子):Material Theme

由於我們專案裡設定了toobar的高度,這裡指定了actionBarSize,然後通過設定toolbar高度為這個值;

佈局程式碼

由於專案中toolbar歸屬於fragment管理,所以這裡是將toolbar封裝在fragment中處理了,這裡通過各個fragment的xml新增<include layout="@layout/toolbar_layout"/>

toolbar_layout.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:elevation="1dp">
    <TextView
        android:id="@+id/nav_left_text"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:drawableLeft="@drawable/nav_back_light"
        android:drawableStart="@drawable/nav_back_light"
        android:layout_gravity = "start"
        android:gravity="center"
        android:minWidth="50dp"
        android:text="返回"
        android:textColor="@android:color/white"
        android:textSize="@dimen/font_title"
        android:visibility="gone"/>
    <TextView
        android:id="@+id/center_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity = "center"
        android:textColor="@android:color/white"
        android:textSize="@dimen/font_large"
        tools:text="標題" />
    <TextView
        android:id="@+id/nav_right_text_button"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity = "end"
        android:gravity="center"
        android:minWidth="50dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:textColor="@color/color_999"
        android:textSize="@dimen/font_normal"
        android:visibility="gone" />
</android.support.v7.widget.Toolbar>
複製程式碼

toolbar上的東西被我分成五種:

  1. navigationicon:通過.setNavigationIcon去處理
  2. logo:通過setlogo
  3. title與subtitle:通過.setTitle與setSubtitle去處理
  4. 自定義部分:這裡也分成左中右三個部分,可以看上面佈局檔案,通過標籤android:layout_gravity 來指定位置,這裡有坑,自定義部分佈局最左邊有間隙,如果要去掉,可以設定:contentInset 這個標籤去除。
  5. menu:menu的顯示方式可以自行設定

這樣來看,基本所有的需求都能滿足了;

fragment中抽象封裝:

這裡要看各個專案需求,由於我們公司專案中對最右邊圖示靈活度要求並不高,我一般使用menu就可以解決了,如果menu不能滿足你,完全可以使用自定義部分中的“右部分”。

下面進入封裝,在baseFragment中做了如下封裝,專案中使用的是JakeWharton的注入框架butterknife連結

  1. 首先注入toolbar及自定義部分中除最右邊圖示的控制元件,因為最右邊圖示我們專案中一般menu就夠用了:
 @BindView(R.id.toolbar)
 protected Toolbar mToolBar;
 @BindView(R.id.center_title)
 TextView mCenterTitle;
 @BindView(R.id.nav_left_text)
 TextView mNavLeftText;
複製程式碼
  1. 然後在初始化fragment檢視時候將mToolBar、mCenterTitle、mNavLeftText傳給其子fragment進行定製,這三個控制元件傳遞出去後完全可以定製navigationicon、logo、title與subtitle、自定義部分這四個部分。以下程式碼中的initview和popFragment是我封裝好的在fragment的OncreateView時候呼叫的,詳細封裝請看:淺談Activity,Fragment模組化封裝
@Override
protected void initView(View view, Bundle savedInstanceState) {
      initToolBar(mToolBar, mCenterTitle, mNavLeftText);
}
複製程式碼
protected void initToolBar(Toolbar toolbar, TextView centerTitle, TextView navLeftText){
        ((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
        ((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(false);
toolbar.setNavigationIcon(R.drawable.nav_back_light);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popFragment();
            }
        });
    }
複製程式碼

這裡有個坑:

((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(false);
複製程式碼

必須設定這個,不然預設的title一直在,即使你設定了toolbar.settitle("xxoo")。。。

這裡做了一件事,給navigationButton導航按鈕做了個監聽,pop出當前這個fragment出棧

  1. 還剩最後一個東西沒有定製:menu

這個很簡單,不過也要注意下,必須在fragment中設定選單,一定要先設定:

setHasOptionsMenu(true);
複製程式碼

關於原始碼,可以去看下,然後處理方式很簡單了:

@Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.search, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }
複製程式碼

這裡也有個坑:如果你沒有設定:

((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
複製程式碼

那麼onCreateOptionsMenu 並不會被回撥。

  1. 最後做下menu的監聽即可:
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()){
                    }
                return true;
            }
        });
複製程式碼

總結

Toolbar是android5.0之後出現的MD設計風的控制元件,支援5.0之後的elevation特性,相比較Actionbar具有高度自定義的特性,因為其本身是一個ViewGroup內部佈局完全自由處理,這樣大大擴充套件了其自由定製性,不多說,趕緊開始替換Actionbar吧!

具體程式碼請看我的github:Android練習小專案

相關文章