Toolbar
先上一張圖
谷歌官方對Toolbar的介紹
根據圖中的資料,可以知道,Toolbar首先是一個ViewGroup,它是用來做APP的標題欄,其中包括5個部分,分別是一個導航按鈕(a navigation button)、一個logo圖片(a branded logo image)、一個標題和副標題(a title and subtitle)、一個或多個自定義View(one or more custom views)以及一個action menu( an action menu)。看一張效果圖
具體效果圖
從效果圖中,我們可以很明顯地看出來5個部分都是哪裏,因爲Toolbar是一個ViewGroup,你只有都設置出來了纔會顯示,如果不設置的話,那麼都是空的,啥也沒有。那麼究竟應該怎麼設置呢?下面我們就開始使用Toolbar。
Toolbar的正確使用姿勢
第一步 導入v7包
implementation 'com.android.support:appcompat-v7:27.0.2
第二步 繼承AppCompatActivity
public class MainActivity extends AppCompatActivity
第三步 設置主題theme
<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/Theme.AppCompat.NoActionBar">
這裏如果不想讓所有的app共用一個主題,可以不在application中設置,可以在單獨的activity裏面設置。
第四步 各種設置
前三步都很簡單,而且基本都是新建項目都能創建好的,這裏就不多講了,重點就在這第四步怎麼設置這裏了。
首先,在佈局文件中的基本屬性設置:
<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"
android:theme="@style/Base.Theme.AppCompat.Light"
app:popupTheme="@style/toolBar_pop_item"
>
這裏的屬性設置了導航按鈕、logo和主標題副標題,屬性名稱很清楚不多講,action menu的設置需要通過代碼,自定義View放到後面來講。
導航Button設置點擊事件
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();
}
});
設置action menu
//設置移除圖片 如果不設置會默認使用系統灰色的圖標
mToolbar.setOverflowIcon(getResources().getDrawable(R.drawable.icon_action));
//填充menu
mToolbar.inflateMenu(R.menu.toolbar_menu);
//設置點擊事件
mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case R.id.action_settings:
Toast.makeText(MainActivity.this,"action_settings",Toast.LENGTH_SHORT).show();
break;
case R.id.action_share:
Toast.makeText(MainActivity.this,"action_share",Toast.LENGTH_SHORT).show();
break;
case R.id.action_search:
Toast.makeText(MainActivity.this,"action_search",Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return false;
}
});
你發現設置了這一對之後,action menu 依然沒有顯示出來,因爲你還沒有重寫onCreateOptionsMenu,讓action menu顯示出來。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_menu,menu);
return true;
}
加上這個重寫方法以後,action menu就會顯示,如同上面的介紹圖一樣,這個時候有朋友就可能問了,爲啥action menu在標題欄上顯示這麼多圖標
action menu
下面我們來看一下R.menu.toolbar_menu這個配置文件
<?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">
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="測試1"
android:icon="@drawable/icon_search"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_share"
android:orderInCategory="100"
android:title="測試2"
android:icon="@drawable/icon_notify"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_search"
android:orderInCategory="100"
android:title="設置"
app:showAsAction="never"/>
<item
android:id="@+id/action_search2"
android:orderInCategory="100"
android:title="關於"
app:showAsAction="never"/>
</menu>
這其中app:showAsAction屬性的作用是來控制item在標題欄上展示的形式,一般多取三個值:always、ifRoom以及never。always:總是展示在標題欄上;ifRoom如果標題欄上有位置就展示出來;never:永不展示標題欄。我這裏設置的是前兩個item的showAsAction屬性是ifRoom,後兩個是never,所以在狀態欄上前兩個圖標被展示出來了,因爲還有兩個item未被在標題欄上顯示出來,系統會默認一個圖標讓用戶來點擊。這裏如果我們把mToolbar.setOverflowIcon(getResources().getDrawable(R.drawable.icon_action)); 這句代碼註釋掉,結果就會是這樣
系統默認的圖標
,如果沒有未被展示的item,這裏就不會出現這個圖標。
點擊溢出圖標,系統默認的彈出樣式是這樣的
系統默認彈出樣式
沒錯,就是這麼醜,那麼怎麼設置一下這個彈出框,能讓它變得好看一些,並且符合我們設計師的要求呢?在xml文件裏
設置彈出框的屬性
就是通過app:popupTheme屬性來控制的,在style文件裏可以設置風格、字體顏色大小等等屬性。簡單看一下toolBar_pop_item
<style name="toolBar_pop_item" parent="Base.Theme.AppCompat.Light">
<item name="android:textColor">@color/colorAccent</item>
</style>
看一下現在的效果
設置style之後的效果
具體的效果根據UI設計師的設計手稿來定
小結
關於ToolBar的使用,在xml佈局文件裏面,可以通過屬性設置好導航Button、logo圖標以及正副標題,在代碼可以設置導航Button的點擊事件,action menu通過代碼來設置,如果要顯示出來記得重寫onCreateOptionsMenu(Menu menu)方法,關於讓menu裏面的item在標題欄中的顯示通過showAsAction屬性來控制,常用的三個屬性分別是always、ifRoom以及never,item彈出的樣式可以通過style文件來設置。知道這些,基本就可以完成標題欄導航欄、logo圖標、正副標題已經action menu的設置了,關於自定義View,下面會單獨拿出來講。
標題居中問題和自定義Toolbar
關於標題居中問題,我看很多小夥伴們都提出過,其實解決起來非常的簡單,就是利用自定義View。之前文中提到過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"
/>
<EditText
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:layout_centerHorizontal="true"
android:background="@drawable/search_bg"
android:drawableLeft="@drawable/icon_search"
android:padding="5dp"
android:textColorHint="#fff"
android:hint="請輸入搜索內容"
android:gravity="center"
android:cursorVisible="false"
/>
</RelativeLayout>
</android.support.v7.widget.Toolbar>
通過這種自定義View方式就可以解決標題居中的問題,看一下效果
標題居中效果
注意這裏返回鍵不要通過Toolbar的導航Button設置,這樣會影響標題居中的效果,直接在自定義View裏面設置就行了。
有些App用搜索框,其實也是利用自定義View來實現,實現起來也很簡單,搜索框在中間跟標題重疊,通過設置可見性來調控,簡單看一下效果
搜索標題欄
寫到這裏,肯定會有小夥伴問了,這裏使用Toolbar有什麼用,我自己寫一個RelativeLayout或者其他什麼佈局都能實現,爲啥非要用Toolbar呢?這裏說一下,使用Toolbar比起傳統的自定義佈局的好處。第一、不需要考慮標題欄和系統狀態欄匹配的問題,你自己寫還得匹配系統狀態欄;第二、就是Toolbar可以和其他的MD設計風格的空間連用,做出比較炫的效果,比如Toolbar+NestScrollView,Toolbar+DrawerLayout + NavigationView等等;第三、谷歌推薦的控件當然要用(嘿嘿,強行湊三條)。
總結
Toolbar是一個ViewGroup,用來做App的標題欄,主要有5部分,導航Button、logo、正副標題、自定義View以及action menu。通過xml文件屬性可以設置導航Button、logo和正副標題,通過代碼設置action menu,利用自定義View可以解決標題不居中的問題。
最後的最後,放上文中demo的地址:https://github.com/kaka10xiaobang/ToolbarDemo