ToolBar的基本使用
简介
toolbar是Android5.0时代替actionbar的控件(兼容5.0以下的使用V7中的toolbar),可以设置:导航图标 + App Logo + Title + SubTitle + customView + action menu
导包:
compile 'com.android.support:appcompat-v7:24.2.1'
1 设置导航图标
2 设置app logo
3 设置标题+子标题
4 添加自定义view
5 添加action menu
基本使用 ##
navatigation +app logo + title +subtitle可以进行代码设置,也可以xml中设置
代码中使用
Toolbar toobar = (Toolbar) findViewById(R.id.toobar);
toobar.setNavigationIcon(R.mipmap.ic_drawer_home);
toobar.setLogo(R.mipmap.ic_launcher);
toobar.setTitle("Title");
toobar.setSubtitle("Subtitle");
//menu:
toobar.inflateMenu(R.menu.menu_toobar);
toobar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_ic_search:
Toast.makeText(context,"ic_search",Toast.LENGTH_SHORT).show();
break;
case R.id.menu_ic_notification:
Toast.makeText(context,"notification",Toast.LENGTH_SHORT).show();
break;
case R.id.menu_item1:
Toast.makeText(context,"menu_item1",Toast.LENGTH_SHORT).show();
break;
case R.id.menu_item2:
Toast.makeText(context,"menu_item2",Toast.LENGTH_SHORT).show();
break;
}
return false;
}
});
布局中使用
注意:Toolbar的根布局中要使用:xmlns:toobar=”http://schemas.android.com/apk/res-auto” ,不然toolbar的属性值无效,其中toolbar是自定义的,一般定义为app。
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:toobar="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.cqc.toobardemo01.MainActivity">
<!--xml设置属性navigationIcon + logo + title + subtitle,需要自定义命名空间 -->
<!-- xmlns:toobar="http://schemas.android.com/apk/res-auto"-->
<android.support.v7.widget.Toolbar
android:id="@+id/toobar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#303F9F"
toobar:logo="@mipmap/ic_launcher"
toobar:navigationIcon="@mipmap/ic_drawer_home"
toobar:popupTheme="@style/Theme.Toolbar.base"
toobar:subtitle="subtitle"
toobar:title="Title">
<TextView
android:id="@+id/tv_custom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text"/>
</android.support.v7.widget.Toolbar>
</LinearLayout>
menu_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">
<!--menu 使用showAsAction 需要xmlns:app="http://schemas.android.com/apk/res-auto"-->
<!--其中 app是自定义的-->
<item
android:id="@+id/menu_ic_search"
android:icon="@mipmap/ic_search"
android:title="search"
app:showAsAction="always"/>
<item
android:id="@+id/menu_ic_notification"
android:icon="@mipmap/ic_notifications"
android:title="notification"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/menu_item1"
android:title="menu_item1"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/menu_item2"
android:title="menu_item2"
app:showAsAction="ifRoom"/>
</menu>
Toolbar的高级使用
属性
title暂用的空间是这个toolbar剩余的,如果menu过大,会挤压title的空间,title过长的话,会省略显示即“…”,
xml
<android.support.v7.widget.Toolbar
android:id="@+id/toolBar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/toolbarBG"
app:navigationIcon="@mipmap/ic_menu_white"
app:logo="@mipmap/ic_launcher"
app:titleMarginStart="10dp"
app:title="@string/app_name"
app:titleTextColor="@android:color/white"
app:titleTextAppearance="@style/ToolbarTitleTextAppearance"
app:popupTheme="@style/Theme.Toolbar.menu"/>
其它:
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
xml + meth
xml属性 | 对应的方法 | 含义 |
---|---|---|
android:background= | setBackGround(int resId) | 整个Toolbar的背景色 |
app:navigationIcon= | setNavigationIcon(int resId) | 导航栏图标 |
app:logo= | setLogo(int resId) | Toolbar的logo(通常与navigationIcon的间距过大) |
app:title= | setTitle(String title) | 标题 |
app:titleTextColor= | setTitleTextColor(int color) | 字体颜色 |
app:titleTextAppearance= | setTitleTextAppearance(int style) | style:字体大小+颜色 |
app:titleMargin=”“ | setTitleMargin(int margin) | 间距 |
app:titleMarginStart= | setTitleMarginStart(int margin) | 左间距 |
app:titleMarginEnd=”“ | setTitleMarginEnd(int margin) | 右间距 |
app:titleMarginTop=”“ | setTitleMarginTop(int margin) | 上间距 |
app:titleMarginBottom=”“ | setTitleMarginBottom(int margin) | 下间距 |
app:subtitle=”subtitle” | setSubtitle(String subtitle) | 子标题内容 |
app:subtitleTextColor=”“ | setSubtitleTextColor(int clolor) | 子标题文字颜色 |
toobar:subtitleTextAppearance=”“ | setSubtitleTextAppearance(Context context,int style) | 子标题style:文字大小+颜色 |
app:popupTheme=”“ | toolbar.setPopupTheme(int resId) | menu的Style:字体大小和颜色 |
Title + SubTitle 的Style
Toolbar的title和subTitle的字体大小在xml中无法直接设置,必须通过style中的android:textSize=属性更改字体大小。
<!--Toobar的字体style-->
<!-- parent="Base.TextAppearance.AppCompat.Title"也可以-->
<style name="ToolbarTitleTextAppearance" parent="Base.TextAppearance.Widget.AppCompat.Toolbar.Title">
<item name="android:textSize">18sp</item>
</style>
//颜色
toobar.setTitleTextColor(0x33fb4804);
toobar.setSubtitleTextColor(0xBB000000);
//style:字体大小+颜色
toobar.setTitleTextAppearance(context,android.support.annotation.StyleRes int resId);
toobar.setSubtitleTextAppearance(context,android.support.annotation.StyleRes int resId);
menu的Style
<!--toolbar 设置action menu-->
<style name="Theme.Toolbar.base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="actionMenuTextColor">#fb4804</item><!--无效-->
<item name="android:textColorPrimary">#fb4804</item>
<item name="android:textSize">25sp</item><!--menu的字体-->
<item name="android:colorBackground">@color/mtrl_white_100</item><!--menu的背景色-->
</style>
在xml中引用:
app:popupTheme="@style/Theme.Toolbar.base"
其他
app:popupTheme="@style/AppTheme.PopupOverlay"
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
menu的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">
<!--menu 使用showAsAction 需要xmlns:app="http://schemas.android.com/apk/res-auto"-->
<!--其中 app是自定义的-->
<item
android:id="@+id/menu_ic_search"
android:icon="@mipmap/ic_search"
android:title="search"
app:showAsAction="always"/>
<item
android:id="@+id/menu_ic_notification"
android:icon="@mipmap/ic_notifications"
android:title="notification"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/menu_item1"
android:title="menu_item1"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/menu_item2"
android:title="menu_item2"
app:showAsAction="ifRoom"/>
</menu>
2种方式填充menu?
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
或者
toobar.inflateMenu(R.menu.menu_toobar);
为什么在Fragment中调用onCreateOptionsMenu(Menu menu, MenuInflater inflater)无效?
原因
通过查看该方法源码,我们在其方法注释中看到着了一句
For this method to be called, you must have first called {@link #setHasOptionsMenu}
也就是在fragment中如果想给actionbar或者toolbar添加menu,必须先调用setHasOptionsMenu()
,一般在oncreate()方法中调用。
解决:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu,inflater);
inflater.inflate(R.menu.tab_2_frag, menu);
}
2种方式点击menu
toobar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_ic_search:
Toast.makeText(context,"ic_search",Toast.LENGTH_SHORT).show();
break;
return false;
}
或者:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
怎么设置Title与Logo的间距 ?
XML:
app:titleMarginStart="10dp"
代码:
toolbar.setTitleMarginStart(int margin);
怎么让title居中?
让title
居中,使用属性app:title="Title"
,实现不了,通过给Toolbar
设置子View
,让其居中来实现。但是这样的话,调用toolbar.setTitle("修改个人信息");
无效。
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="text"/>
为了解决这个bug,我们需要将TextView
的宽改为wrap_content
,android:layout_gravity="center"
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="@color/primary">
<TextView
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="20sp" />
</android.support.v7.widget.Toolbar>
点击事件
navatigation 的点击事件,menu的点击事件
app logo + title +subtitle 没有点击事件
toobar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context,"NavigationIcon",Toast.LENGTH_SHORT).show();
}
});
toobar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_ic_search:
Toast.makeText(context,"ic_search",Toast.LENGTH_SHORT).show();
break;
case R.id.menu_ic_notification:
Toast.makeText(context,"notification",Toast.LENGTH_SHORT).show();
break;
case R.id.menu_item1:
Toast.makeText(context,"menu_item1",Toast.LENGTH_SHORT).show();
break;
case R.id.menu_item2:
Toast.makeText(context,"menu_item2",Toast.LENGTH_SHORT).show();
break;
}
return false;//改成true也可以,为什么??
}
});
将ActionBar改成Toolbar
Activity:
public Toolbar initToolbar(String title) {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(title);
setSupportActionBar(toolbar);
android.support.v7.app.ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
return toolbar;
}
fragment:
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
在Toolbar上设置SearchView
如果用系统的view,那么使用actionViewClass
,当然,也可以自定义layout,这时就需要用actionLayout
menu_main.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">
<!--android:actionViewClass="android.widget.SearchView" activity继承自V7包的AppCompatActivity,那么就必须使用V7下的SearchView-->
<item
android:id="@+id/app_bar_search"
app:actionViewClass="android.support.v7.widget.SearchView"
android:icon="@drawable/ic_search_black_24dp"
app:showAsAction="ifRoom|collapseActionView"
android:title="Search"/>
</menu>
获取SearchView和设置缩放监听:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
//获取 SearchView
MenuItem searchItem = menu.findItem(R.id.app_bar_search);
MenuItemCompat.OnActionExpandListener onActionExpandListener = new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
ToastUtil.showShortToast(context, "expand");
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
ToastUtil.showShortToast(context, "collapse");
return true;
}
};
MenuItemCompat.setOnActionExpandListener(searchItem, onActionExpandListener);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);//过时
return true;
}
在toolbar内部添加子view,左侧会有空白
参考:使用Toolbar/ActionBar自定义布局时,左侧/右侧有一段无法使用
如图:
修改方法,给toolbar添加参数:
app:contentInsetStart="0dp"
当然,也有另一个属性
app:contentInsetRight="0dp"
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
app:contentInsetStart="0dp"
app:contentInsetRight="0dp"
app:layout_collapseMode="pin">
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_margin="0dp"
android:background="#f00"
app:tabGravity="center"
app:tabMode="scrollable"/>
</android.support.v7.widget.Toolbar>