Toolbar 繼承的是ViewGroup,用來替代原來的ActionBarjava
一個Toolbar 從左到右包括了 一個navigation button、一個logo、一個title和subtitle、一個或多個自定義的View和一個 action menu 這5部分android
mToolbar = findViewById(R.id.toolbar);
mMenuView = findViewById(R.id.toolbar_action_menu);
mToolbar.setTitle("John");
mToolbar.setNavigationIcon(R.drawable.ic_menu);
mToolbar.setNavigationOnClickListener(this::OnBackClick);
mToolbar.setSubtitle("Sub");
// 設置溢出菜單的圖標
// mToolbar.setOverflowIcon(ContextCompat.getDrawable(getApplicationContext(),R.drawable.menu));
mToolbar.inflateMenu(R.menu.toolbar_menu);
mToolbar.setOnMenuItemClickListener(menuItem -> {
//利用colorFilter動態更改圖標顏色
// menuItem.getIcon().setColorFilter(Color.parseColor("#223344"),PorterDuff.Mode.MULTIPLY);
switch (menuItem.getItemId()){
case R.id.toolbar_call:
Toast.makeText(MainActivity.this,"toolbar_call",Toast.LENGTH_SHORT).show();
break;
case R.id.toolbar_delete:
Toast.makeText(MainActivity.this,"toolbar_delete",Toast.LENGTH_SHORT).show();
break;
case R.id.toolbar_mail:
Toast.makeText(MainActivity.this,"toolbar_mail",Toast.LENGTH_SHORT).show();
break;
}
return true;
});
複製代碼
亦能夠經過
setSupportActionbar
,再調用getSupportActionBar
,當成actionBar使用,若沒有則,setSupportActionbar
,則onCreateOptionsMenu
不會回調bash
Theme.AppCompat.Light.NoActionBar
<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>
<!--更改menu item間隔-->
<item name="android:actionButtonStyle">@style/MyActionButtonStyle</item>
</style>
複製代碼
MyActionButtonStyle:app
<!--menu item 之間的間隔-->
<style name="MyActionButtonStyle" parent="Widget.AppCompat.ActionButton">
<item name="android:minWidth">72dip</item>
</style>
複製代碼
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/MyToolBarTheme"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:titleTextAppearance="@style/Toolbar.TitleText"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
</android.support.v7.widget.Toolbar>
複製代碼
MyToolbarTheme:ide
<style name="MyToolBarTheme" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
<!--更改溢出菜單文字顏色-->
<item name="android:textColor">@color/colorAccent</item>
<!--更改toolbar菜單文字大小,包括溢出菜單上的,和顯示上的-->
<item name="android:textSize">25sp</item>
<!--更改toolbar上的菜單顯示文字顏色-->
<item name="android:actionMenuTextColor">@color/colorPrimaryDark</item>
<!-- 設置Menu窗口不覆蓋Toolbar視圖 -->
<item name="overlapAnchor">false</item>
<!--設置title與navigationIcon的間隔-->
<item name="contentInsetStart">0dp</item>
<item name="contentInsetLeft">0dp</item>
<item name="contentInsetStartWithNavigation">0dp</item>
</style>
複製代碼
Toolbar.TitleText:佈局
<!--Toolbar標題文字大小-->
<style name="Toolbar.TitleText" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
<item name="android:textSize">15sp</item>
</style>
複製代碼
<item name="android:textColor">@color/colorAccent</item>
post
<item name="android:textSize">25sp</item>
字體
<!--Toolbar標題文字大小-->
<style name="Toolbar.TitleText" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
<item name="android:textSize">15sp</item>
</style>
複製代碼
<item name="android:actionMenuTextColor">@color/colorPrimaryDark</item>
<item name="overlapAnchor">false</item>
<item name="contentInsetStart">0dp</item>
<item name="contentInsetLeft">0dp</item>
<item name="contentInsetStartWithNavigation">0dp</item>
複製代碼
<item name="android:actionButtonStyle">@style/MyActionButtonStyle</item>
ui
MyActionButtonStyle:this
<style name="MyActionButtonStyle" parent="Widget.AppCompat.ActionButton">
<item name="android:minWidth">72dip</item>
</style>
複製代碼
如有使用
setSupportActionBar()
,則調用getSupportActionBar().setDisplayShowTitleEnabled(false);
隱藏標題;若沒設置,只要toolbar不設置title便可
只對setSupportActionBar起做用
// 讓菜單同時顯示圖標和文字
@SuppressWarnings("PrivateApi")
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
if (menu != null) {
if (menu.getClass().getSimpleName().equalsIgnoreCase("MenuBuilder")) {
try {
Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
method.setAccessible(true);
method.invoke(menu, true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return super.onMenuOpened(featureId, menu);
}
複製代碼
菜單默認在最右邊,使用ActionMenuView可更改菜單顯示位置,並能夠動態刪除添加菜單
mMenuView = findViewById(R.id.toolbar_action_menu);
//加載菜單
getMenuInflater().inflate(R.menu.toolbar_menu,mMenuView.getMenu());
//設置菜單監聽
mMenuView.setOnMenuItemClickListener(menuItem -> {
switch (menuItem.getItemId()){
case R.id.toolbar_call:
Toast.makeText(MainActivity.this,"toolbar_call",Toast.LENGTH_SHORT).show();
break;
case R.id.toolbar_delete:
Toast.makeText(MainActivity.this,"toolbar_delete",Toast.LENGTH_SHORT).show();
break;
case R.id.toolbar_mail:
Toast.makeText(MainActivity.this,"toolbar_mail",Toast.LENGTH_SHORT).show();
break;
}
//動態改變菜單
mMenuView.getMenu().clear();
getMenuInflater().inflate(R.menu.nav_menu,mMenuView.getMenu());
return true;
});
複製代碼
<item
android:id="@+id/toolbar_delete"
android:title="delete"
android:icon="@drawable/ic_delete"
android:orderInCategory="100"
app:actionViewClass="android.widget.Button"
app:showAsAction="always"/>
複製代碼
最後在java中獲取對象
MenuItem item = menu.findItem(R.id.toolbar_delete);
Button button = (Button) item.getActionView().findViewById(R.id.menu_button);
button.setOnClickListener(view -> {
Toast.makeText(MainActivity.this,"Button",Toast.LENGTH_SHORT).show();
});
複製代碼
注意: 若調用setSupportActionBar
,則在onCreateOptionsMenu(Menu menu)
中獲取menu引用,不然直接Menu menu = mToolbar.getMenu();
<item
android:id="@+id/toolbar_delete"
android:title="delete"
android:icon="@drawable/ic_delete"
android:orderInCategory="100"
app:actionLayout="@layout/menu_action"
app:showAsAction="always"/>
複製代碼
注意:menu_action佈局文件的內容必須以RelativeLayout做爲根容器佈局,不然,actionLayout 對應的視圖寬度不足以填充滿 Toolbar 或者說 ActionBar 的寬度,顯示效果如同設置 layout_width 屬性值爲 wrap_content 通常。
注意:第二,actionLayout 屬性必須使用 app 做爲命名空間,若是使用 android 的話,會致使 menuItem 對象經過 getActionView() 始終獲取的對象爲 null 。
最後在java中獲取對象
MenuItem item = menu.findItem(R.id.toolbar_delete);
Button button = (Button) item.getActionView().findViewById(R.id.menu_button);
button.setOnClickListener(view -> {
Toast.makeText(MainActivity.this,"Button",Toast.LENGTH_SHORT).show();
});
複製代碼
注意: 若調用setSupportActionBar
,則在onCreateOptionsMenu(Menu menu)
中獲取menu引用,不然直接Menu menu = mToolbar.getMenu();
有時候須要在Fragment中使用Toolbar,好比Activity中不一樣的Tab顯示不一樣的Fragment,同時每一個Tab的Toolbar標題、Menu均不相同,這時在Activity中使用同一個Toolbar就至關不方便了。咱們能夠在每一個Fragment的佈局中添加各自的Toolbar,而後在Fragment中單獨控制。
與Activity中使用Toolbar有所不一樣。替換ActionBar時,須要給setSupportActionBar方法添加做用對象:
((AppCompatActivity)getActivity()).setSupportActionBar((Toolbar) mContentView.findViewById(R.id.tb_toolbar));
複製代碼
添加Options Menu時,須要額外調用setHasOptionsMenu(true);方法,確保onCreateOptionsMenu()方法得以調用,而且onCreateOptionsMenu()方法多了一個MenuInflater參數:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.search, menu);
}
複製代碼
注意: MenuItem 的點擊事件會先執行宿主 Activity 中的 onOptionsItemSelected 方法,而後再將事件傳遞到 Fragment 中。因此,若是須要覆蓋或者說屏蔽 Activity 的影響,須要在宿主 Activity 中修改該方法的返回值爲 flase,如:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
...
return false;
}
複製代碼