Android中Toolbar (2)
上篇博客,粗略的说到了官方对于toolbar的使用,如有不熟悉可去Android中Toolbar(1)http://blog.csdn.net/hj2drf/article/details/61430582现在聊聊日常开发中的使用:Toolbar继承ViewGroup是一个容器类,里面可以添加很多子视图组件,
上篇博客,粗略的说到了官方对于toolbar的使用,如有不熟悉可去Android中Toolbar(1)http://blog.csdn.net/hj2drf/article/details/61430582
现在聊聊日常开发中的使用:
Toolbar继承ViewGroup是一个容器类,里面可以添加很多子视图组件,
常用的API如下所示:
1)public void setBackgroundColor(int color) // 设置背景颜色
2)public void setTitle(CharSequence title) // 设置主标题
3)public void setTitleTextColor(@ColorInt int color) // 设置主标题颜色
4)public void setSubtitle(CharSequence subtitle) // 设置副标题
5)public void setSubtitleTextColor(@ColorInt int color) // 设置副标题颜色
6)public void setNavigationIcon(@DrawableRes int resId) // 设置导航图标
7)public void setNavigationOnClickListener(OnClickListener listener) // 设置导航监听事件
8)public void setLogo(@DrawableRes int resId) // 设置logo图标
9)public void setTitleTextAppearance(Context context, @StyleRes int resId) // 设置主标题样式
10)public void setSubtitleTextAppearance(Context context, @StyleRes int resId) // 设置副标题样式
11)public void inflateMenu(@MenuRes int resId) // 设置actionmenu
12)public void setOnMenuItemClickListener(OnMenuItemClickListener listener) // 设置菜单点击事
在使用toolbar需要注意:
setSupportActionBar()方法的调用地方
如果setSupportActionBar() 调用的位置太靠前,会使得Toolbar的部分设置没有效果,例如把setSupportActionBar()方法在setTitle方法前调用,Toolbar的title将显示我们的项目名,而不是我所填写的知乎。最好是在Toolbar的所有设置都已经完成后调用setSupportActionBar()方法。
menu的使用
在Toolbar中有一个inflateMenu()的方法,通过该方法可以设置Toolbar上面的OptionsMenu.如果使用了setSupportActionBar(),那么inflateMenu()方法无效,此时需使用重写activity中的onCreateOptionsMenu()方法来创建Menu。相反,如果没调用setSupportActionBar()方法的话,此时是靠inflateMenu()方法来创建Menu
首先从setSupportActionBar()方法说起,这个方法我试过不掉用,也没什么异样(除了对Menu的影响),调用此方法,对ActionBar的设置都会把相应的属性设置到Toolbar上,
实例
1)创建一个布局,在其中添加Toolbar,使用v7包下的
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
app:navigationIcon="@drawable/ic_action_name"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.Toolbar>
</RelativeLayout>
2)activity需要继承AppCompatActivity,theme设置android:theme=”@styleTheme.AppCompat.NoActionBar”
public class ToolbarActivity extends AppCompatActivity {
private Toolbar mToolbar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_toolbar);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
//设置背景色
mToolbar.setBackgroundColor(Color.BLACK);
//设置主标题
mToolbar.setTitle("主标题");
//设置主标题文字颜色
mToolbar.setTitleTextColor(Color.WHITE);
//设置主标题统一样式(包括颜色,字体,字号)
//mToolbar.setTitleTextAppearance(this, R.style.xxx);
//设置副标题
mToolbar.setSubtitle("副标题");
//设置副标题文字颜色
mToolbar.setSubtitleTextColor(Color.LTGRAY);
//设置副标题统一样式(包括颜色,字体,字号)
//mToolbar.setSubtitleTextAppearance(this, R.style.xxx);
//设置logo
mToolbar.setLogo(R.mipmap.ic_launcher);
//设置导航图标,注意布局中设置的话使用app的
mToolbar.setNavigationIcon(R.drawable.ic_action_name);
//设置导航图标点击事件
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Snackbar.make(v, "测试信息", Snackbar.LENGTH_SHORT).show();
}
});
//添加menu
mToolbar.inflateMenu(R.menu.menu_main);
//设置menu的点击事件
mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
int menuId = item.getItemId();
switch (menuId) {
case R.id.action_settings:
Snackbar.make(mToolbar, "单击setting", Snackbar.LENGTH_SHORT).show();
break;
case R.id.action_about:
Snackbar.make(mToolbar, "单击about", Snackbar.LENGTH_SHORT).show();
break;
case R.id.action_exit:
Snackbar.make(mToolbar, "单击exti", Snackbar.LENGTH_SHORT).show();
break;
}
return true;
}
});
}
}
3)menu菜单配置文件
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_settings"
android:title="@string/action_settings"
android:orderInCategory="100"
app:showAsAction="never" />
<item
android:id="@+id/action_about"
android:orderInCategory="200"
app:showAsAction="never"
android:title="About"/>
<item
android:id="@+id/action_exit"
android:orderInCategory="300"
app:showAsAction="never"
android:title="Exit"/>
<item android:id="@+id/my_search"
android:title="@string/search_title"
android:icon="@drawable/ic_open_search"
app:showAsAction="ifRoom"
app:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
可以看到,我在这里定义了4个item,分别对应setting,about,exit,search,对于item是否直接显示在toolbar上,取决于app:showASAction=”“的值
其中showAsAction属性共有五个值:ifRoom、never、always、withText、collapseActionView,可以混合使用。
ifRoom 会显示在Item中,但是如果已经有4个或者4个以上的Item时会隐藏在溢出列表中。当然个数并不仅仅局限于4个,依据屏幕的宽窄而定
never 永远不会显示。只会在溢出列表中显示,而且只显示标题,所以在定义item的时候,最好把标题都带上。
always 无论是否溢出,总会显示。
withText withText值示意Action bar要显示文本标题。Action bar会尽可能的显示这个标题,但是,如果图标有效并且受到Action bar空间的限制,文本标题有可能显示不全。
collapseActionView 声明了这个操作视窗应该被折叠到一个按钮中,当用户选择这个按钮时,这个操作视窗展开。否则,这个操作视窗在默认的情况下是可见的,并且即便在用于不适用的时候,也要占据操作栏的有效空间。
一般要配合ifRoom一起使用才会有效果。
android:orderInCategory设置menu的优先级,数字越小优先级越高。优先级低的图标在toolbar中menu图标放不下时,自动折叠到最右侧的图标下
特别说一下,search这个item,单击这个item交互是不一样的哦,直接关联了新的空间SerachView
接下来看下效果
下面再说说另一种是用方式:
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
这个时候就需要取代上一种menu的创建方法及单击事件,通过
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int menuId = item.getItemId();
switch (menuId) {
case R.id.action_settings:
Snackbar.make(mToolbar, "单击setting", Snackbar.LENGTH_SHORT).show();
return true;
case R.id.action_about:
Snackbar.make(mToolbar, "单击about", Snackbar.LENGTH_SHORT).show();
return true;
case R.id.action_exit:
Snackbar.make(mToolbar, "单击exti", Snackbar.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
防止没有Menu按键的手机不显示Menu:
该特性由ViewConfiguration这个类中一个叫做sHasPermanentMenuKey的静态变量控制,系统根据这个变量的值来判断手机有没有物理Menu键的。当然这是一个内部变量,无法直接访问它,可以通过反射的方式修改它的值,让它为false。
private void setMenuAlwaysShow() {
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
} catch (Exception e) {
e.printStackTrace();
}
}
此处参考:Android ActionBar完全解析,使用官方推荐的最佳导航栏(上) - 郭霖的专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/guolin_blog/article/details/18234477
配置Menu的icon图标:
在ToolBar的主题中配置name=”actionOverflowButtonStyle”属性,创建一个主题继承自android:style/Widget.Holo.Light.ActionButton.Overflow,配置name=”android:src”属性:
<style name="Theme.ToolBar.Base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:textSize">20sp</item>
<item name="android:textColorPrimary">@color/black_424242</item>
<!--s设置Menu菜单的背景色-->
<item name="android:itemBackground">@color/blue_600</item>
<!--设置menu菜单不遮挡actionbar-->
<item name="actionOverflowMenuStyle">@style/OverflowMenu</item>
<!--配置Menu的图标-->
<item name="actionOverflowButtonStyle">@style/ToolBar.ActionButton.Overflow</item>
</style>
<style name="ToolBar.ActionButton.Overflow" parent="android:style/Widget.Holo.Light.ActionButton.Overflow">
<item name="android:src">@mipmap/ic_menu_more_overflow</item>
</style>
配置Menu菜单的OvweFlow的action:
基本和ActionBar相同
配置OvweFlow中的action文字颜色:
在ToolBar的主题中配置android:textColorPrimary属性
<style name="Theme.ToolBar.Base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:textSize">20sp</item>
<item name="android:textColorPrimary">@color/color_red</item>
</style>
或者在Toolbar的 app:popupTheme=”@style/AppTheme.PopupOverlay”主题中配置android:textColorPrimary属性:
app:popupTheme="@style/AppTheme.PopupOverlay"
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light">>
<item name="android:textColorPrimary">#fff</item>
</style>
配置OvweFlow中的action背景:
在ToolBar的主题中配置android:itemBackground属性
<!--s设置Menu菜单的背景色-->
<item name="android:itemBackground">@color/black_light</item>
配置OvweFlow中的action的宽度:
在Toolbar的popupTheme中设置android:width属性,但是注意Item的宽度有最大最小的限制,超过该限制后显示效果是最大宽度和最小宽度。
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light">
<!--Item的宽度-->
<item name="android:width">400dp</item>
<item name="android:textColorPrimary">#fff</item>
</style>
配置OvweFlow中的action显示icon:
默认情况下OverFlow中只显示文字,但这样不够美观。在Toolbar的popupTheme中设置android:drawableRight android:drawableLeft android:drawableTop android:drawableBottom属性,注意这个设置对所有Item统一生效的,这样也就没有太大的意义。
<!--<item name="android:drawableLeft">@drawable/ic_action_search</item>-->
<item name="android:drawableRight">@drawable/ic_home_gray_36dp</item>
<item name="android:drawableTop">@drawable/ic_textsms_gray_36dp</item>
是否显示Icon是由MenuBuilder这个类的setOptionalIconsVisible方法来决定的,该方法不能直接调用,可以反射之。重写boolean onCreatePanelMenu(int featureId, Menu menu)方法,在menu创建的时候调用之。
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
if (menu != null) {
if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
try {
Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return super.onCreatePanelMenu(featureId, menu);
}
配置OvweFlow中的action间的分割线:
在Toolbar的popupTheme中设置android:dividerHeight属性,设置高度大于0就能显示分割线,分割线的默认颜色是白色。
1dp
配置ToolBar的Menu不遮挡ToolBar:
Actionbar中的配置方式是:设置actionOverflowMenuStyle的android:overlapAnchor属性为false.这里同样,不过注意是在ToolBar的主题中而不是Activity的主题。
<style name="Theme.ToolBar.Base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:textSize">20sp</item>
<item name="android:textColorPrimary">@color/color_red</item>
<!--s设置Menu菜单的背景色-->
<item name="android:itemBackground">@color/gray</item>
<!--设置menu菜单不遮挡actionbar-->
<item name="actionOverflowMenuStyle">@style/OverflowMenu</item>
</style>
<style name="OverflowMenu" parent="Widget.AppCompat.PopupMenu.Overflow">
<!--兼容Api 21之前的版本 -->
<item name="overlapAnchor">false</item>
<!-- Api 21-->
<item name="android:overlapAnchor">false</item>
</style>
配置ToolBar的Home图标左侧间隙
在布局中Toolbar控件中配置属性 app:contentInsetStart=”3dp”
app:contentInsetStart=”3dp”
ToolBar的状态栏沉浸效果:
配置ToolBar和系统状态栏背景色一致:必须配置不使用半透明状态栏才可以设置状态栏颜色,需要android4.4(Api Level 19)及以上
<style name="Theme.MyActivity" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<!--配置是否使用半透明状态栏-->
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowTranslucentNavigation">true</item>
<!--状态栏颜色-->
<item name="android:statusBarColor">@color/color_0176da</item>
</style>
设置Toolbar 浮动:
ToolBar 没有提供显示和隐藏的方法,首先调用 setSupportActionBar(toolbar);方法把ToolBar设置为ActionBar,再使用ActionBar的方式显示隐藏
点击屏幕后显示隐藏ToolBar;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (actionBar == null) {
actionBar = getSupportActionBar();
}
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
if (actionBar != null) {
if (actionBar.isShowing()) {
actionBar.hide();
} else {
actionBar.show();
}
}
break;
}
return super.onTouchEvent(event);
}
但是这样设置setSupportActionBar(toolbar);之后,如果是直接在ToolBar上设置的Menu的方式;toolbar.inflateMenu(R.menu.base_toolbar_menu);ToolBar上的Menu菜单会消失,这时候需要使用复写方式添加Menu
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.base_toolbar_menu, menu);
return true;
}
ToolBar和一个普通控件是一样的,所以浮动效果应该通过布局搞定,设置Toolbar的根布局为相对布局,同时添加一个移动动画
设置Activity的主题:
<style name="ToolbarActivityTheme" parent="AppTheme">
<!--启用ActionBar的叠加模式(不生效)-->
<item name="windowActionBarOverlay">true</item>
<!--状态栏半透明-->
<item name="android:windowTranslucentStatus">true</item>
<!--内容填充到导航栏-->
<item name="android:windowTranslucentNavigation">true</item>
<!--设置全屏-->
<item name="android:windowFullscreen">true</item>
</style>
添加动画和隐藏效果:
@Override
public boolean onTouchEvent(MotionEvent event) {
if (actionBar == null) {
actionBar = getSupportActionBar();
}
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
if (actionBar != null) {
if (actionBar.isShowing()) {
int height = toolbar.getMeasuredHeight();
height = height <= 0 ? 112 : height;
startAnimation(-height, new Runnable() {
@Override
public void run() {
actionBar.hide();
}
});
} else {
actionBar.show();
startAnimation(0, new Runnable() {
@Override
public void run() {
}
});
}
}
break;
}
return super.onTouchEvent(event);
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private void startAnimation(int transY, final Runnable end) {
ViewPropertyAnimator animator = toolbar.animate().translationY(transY).setDuration(600);
animator.start();
animator.setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
end.run();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
配置Activity内容填充到系统状态栏:
这样Activity的整个内容会冲到屏幕顶部,不是导航栏透明
<item name="android:windowTranslucentNavigation">true</item>
ToolBar的navigationIcon一直居上不居中的异常:
排查原因竟然是在Activity中设置ToolBar的主题……哪怕这个主题中什么都不写,这个图标依然会居上,不明白什么原因
<style name="ToolBarActivityTheme" parent="Theme.AppCompat.Light">
<!--使用toolbar取消默认的actionbar-->
<item name="android:windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:actionBarStyle">@style/TranslucentActionBar</item>
<!--设置ActionBar的主题-->
<!--<item name="android:toolbarStyle">@style/ToolBarActivityToolbarTheme</item>-->
<item name="toolbarStyle">@style/ToolBarActivityToolbarTheme</item>
</style>
更多推荐
所有评论(0)