Toolbar詳解(實時更新,未完待續...)
前言:目前為止基本的程式碼都是仿造第一行程式碼所寫,但會實時加入其它複雜的應用。
一,隱藏ActionBar
觀察AndroidMenifest.xml,原來系統預設指定了Theme:AppTheme
<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">
我們去res/value/styles.xml中尋找AppTheme的具體指代
<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>
系統給我們預設設定了一個深色ActionBar主題,我們修改其為NoActionBar或者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>
這樣ActionBar就被隱藏了。
二,在佈局中加入ToolBar控制元件
activity_main.xml
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#1EB9FD"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
</FrameLayout>
?attr/actionBarSize 是R檔案中系統內建的一個值,可以雙擊shift搜尋。
這裡以完整的包的形式匯入了Toolbar,其中theme屬性指定了ToolBar的主題樣式,這裡代表一種深色主題,當然也可以自定義。
三,在MainActivity中引入Toolbar
MainActivity.class
package com.example.slidingmenu;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private Toolbar mToolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar=(Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);//用toolbar替代acitonbar
ActionBar actionBar=getSupportActionBar();
if(actionBar!=null){
actionBar.setDisplayHomeAsUpEnabled(true);//讓導航按鈕顯示
actionBar.setHomeAsUpIndicator(R.mipmap.navigation);//用自己定義的導航欄圖示代替預設的箭頭圖示
}
}
最後兩行增加了一個圖片按鈕,它在android中的名字叫HomeAdUp,在圖片中可以看到,其它比較簡單,就不解釋了。這樣一個基本的ToolBar就顯示出來了.
四,給導航按鈕設定監聽
只需在activity中重寫onOptionsItemSelected方法:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home://HomeAsUp按鈕預設固定的名稱
//做你想做的事
break;
}
return true;
}
五,定製toolbar的menu佈局
右擊res->New->Directory,建立一個menu資料夾,然後在該資料夾下,New->Menu resource file,建立一個toolbar.xml檔案。
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/sift"
android:title="@string/order"
android:icon="@drawable/order"
app:showAsAction="ifRoom">
</item>
<item
android:id="@+id/collect"
android:title="@string/collect"
android:icon="@drawable/collect"
app:showAsAction="never">
</item>
<item
android:id="@+id/share"
android:title="@string/share"
android:icon="@drawable/share"
app:showAsAction="never">
</item>
<item
android:id="@+id/history"
android:title="@string/history"
android:icon="@drawable/history"
app:showAsAction="never">
</item>
<item
android:id="@+id/report"
android:title="@string/report"
android:icon="@drawable/report"
app:showAsAction="never">
</item>
</menu>
這是一個示例。其中:
title:每個item都必須要定義這個屬性,即使你加入了icon。有三個原因:
1,當toolbar空間不足以展示整個item時,系統會只顯示出title內容。
2,為視力缺陷者考慮,那些盲人使用app時,安卓系統可能會通過朗讀title的方式來給他們提供方便
3,長按每個item時會顯示titleShowAsAction:有以下選擇:
1,always:表示永遠顯示在toolbar中,螢幕空間不夠就不顯示
2,ifRoom:如果螢幕空間足夠的情況下顯示在toolbar中,不夠的話顯示在menu中
3,never:表示永遠顯示在menu中
注意顯示在toolbar中的item只顯示圖片(icon賦值),menu中的item只顯示title。
同樣要監聽這些按鈕,也是在onOptionsSelected方法中,選擇對應id即可。
設定完佈局後,我們接下來讓它顯示出來:
在Activity中重寫
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_menu,menu);
return true;
}
如果想要給menu定義點選事件,可以這樣用:
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.collect:
break;
case R.id.sift:
break;
case R.id.history:
break;
case R.id.report:
break;
case android.R.id.home://返回按鈕無法監聽
finish();
break;
}
return true;
}
});
這個方法貌似只能監聽toolbar的menu部分,因為我發現它無法監聽返回按鈕,當然目前只是推測。如果要監測所有部分,那那麼用onOptionSelected方法。
這裡有一個很坑的注意點:
onOptionSelected和onMenuItemClick是有一定衝突的,當兩者都監聽了menu中的同一個單位,那麼點選事件只會傳給onMenuItemClick,這個讀者可以自己去嘗試。
六,動態設定toolbar的標題內容
靜態設定方法:
AndroidManifest.xml檔案
<activity android:name=".activity.DiscussionActivity"
android:label="你想要的標題"/>
這個是一種方式,實際上如果你不做任何設定,toolbar就會採用
<application
android:name=".app.AppApplication"
android:allowBackup="true"
android:icon="@mipmap/launch_icon"
android:label="@string/app_name"
android:theme="@style/AppTheme">
中的label了。
動態設定方法:
toolbar = (Toolbar) findViewById(R.id.discussion_toolbar);
//toolbar.setTitle("你想要的標題");
setSupportActionBar(toolbar);
if(getSupportActionBar!=null)
getSupportActionBar.setTitle("你的標題");
這裡如果你去實踐就會發現,如果你在setSupportActionBar方法後加
toolbar.setTitle();
你會發現沒有任何效果,但你如果用我上面的方法,你會發現是可行的,具體看stack overflow上的解釋:
設定toolbar標題沒有效果