Toolbar使用说明
来源:互联网 发布:淘宝客服差评处理技巧 编辑:程序博客网 时间:2024/05/22 12:42
转载请注明出处:http://blog.csdn.net/forevercbb/article/details/50889282
由于ActionBar的局限性,Google引进Toolbar取代ActionBar,Toolbar可以更方便及更大程度的进行自定义。最近也是粗浅的使用了一下Toolbar,也遇到一些问题,这里分享一下Toolbar的正确使用姿势。
Toolbar的基本使用
1.调整styles.xml
<style name="AppBaseTheme" parent="Theme.AppCompat"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item></style>
使用Theme.AppCompat系列主题,如果应用是白色主题,可以使用Theme.AppCompat.Light.DarkActionBar
2.在布局文件中定义Toolbar控件,跟定义TextView一样,增加app命名空间,一般控件的属性如background、layout属性用android的,Toolbar特有的属性用app命名空间的。
<android.support.v7.widget.Toolbar 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="?attr/actionBarSize" android:background="@drawable/toolbar_bg" app:navigationIcon="@drawable/icon_back_new" app:titleTextColor="#787878" ></android.support.v7.widget.Toolbar>
属性不多,通过属性名基本可以看懂作用。由于应用风格的一致,Toolbar会有较多的相同或相似,因此建议将Toolbar单独定义在一个layout里面,使用时通过include导入即可,既避免重复劳动,日后修改也比较方便。
Background可以设置toolbar的背景,navigationIcon定义返回按钮,只需要在布局文件中设置这个属性,就会出现返回按钮了,无需像Actionbar一样在代码中set个什么鬼的。
3.在代码中获取Toolbar,可以通过代码继续定义toolbar,最后调用setSupportActionBar(),就能用Toolbar替代ActionBar了。
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);toolbar.setTitle(R.string.music);setSupportActionBar(toolbar);
这里需要注意,Activity需要继承v7包的AppCompatActivity才能调用setSupportActionBar()方法。同时Toolbar要导入v7包的,否则只有在API Level 21,也就是Android 5.0以上版本才能使用。
其它还有什么设置logo啊,title啊,subTitle啊,都太简单了,使用任何语言进行描述都显得苍白无力。
这里介绍一下Toolbar的一些自定义颜色属性。
colorPrimaryDark
状态栏背景色。
在 style 的属性中设置。
textColorPrimary
App bar 上的标题与更多菜单中的文字颜色。
在 style 的属性中设置。
App bar 的背景色
Actionbar 的背景色设定在 style 中的 colorPrimary。
Toolbar 的背景色在layout文件中设置background属性。
colorAccent
各控制元件(如:check box、switch 或是 radoi) 被勾选 (checked) 或是选定 (selected) 的颜色。
在 style 的属性中设置。
colorControlNormal
各控制元件的预设颜色。
在 style 的属性中设置
windowBackground
App 的背景色。
在 style 的属性中设置
navigationBarColor
导航栏的背景色,但只能用在 API Level 21 (Android 5) 以上的版本
在 style 的属性中设置
AppCompatActivity中的菜单使用问题
1.AppCompatActivity菜单不会加载Icon。
解决方案:
@Override
protected boolean onPrepareOptionsPanel(View view, Menu menu) {
if (menu != null) {
if (menu.getClass() == MenuBuilder.class) {
try {
Method m = menu.getClass().getDeclaredMethod(“setOptionalIconsVisible”, Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, true);
} catch (Exception e) {
}
}
}
return super.onPrepareOptionsPanel(view, menu);
}
2.使用onPrepareOptionsMenu()会重复加载菜单
解决方法:在onPrepareOptionsMenu方法中调用invalidateOptionsMenu()方法使原来填充的menu无效。
最后说一下setSupportActionBar()方法和getSupportActionBar()方法
setSupportActionBar的参数是Toolbar,而getSupportActionBar取回的却是ActionBar
public abstract void setSupportActionBar(Toolbar toolbar); public abstract ActionBar getSupportActionBar();
跟踪一下源码,由setSupportActionBar()的注释可以知道,Toolbar to set as the Activity’s action bar,该方法实际将Toolbar设置成了Actionbar。但是Toolbar继承于GroupView,而ActionBar没有父类,又是怎么设置的呢。
继续跟踪,在AppCompatDelegateImplV7类找到setSupportActionBar()方法的实现,
public void setSupportActionBar(Toolbar toolbar) { if (!(mOriginalWindowCallback instanceof Activity)) { // Only Activities support custom Action Bars return; } final ActionBar ab = getSupportActionBar(); if (ab instanceof WindowDecorActionBar) { throw new IllegalStateException("This Activity already has an action bar supplied " + "by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set " + "windowActionBar to false in your theme to use a Toolbar instead."); } // Clear out the MenuInflater to make sure that it is valid for the new Action Bar mMenuInflater = null; ToolbarActionBar tbab = new ToolbarActionBar(toolbar, ((Activity) mContext).getTitle(), mAppCompatWindowCallback); mActionBar = tbab; mWindow.setCallback(tbab.getWrappedWindowCallback()); tbab.invalidateOptionsMenu(); }
可以知道Toolbar到ActionBar的转换通过ToolbarActionBar类完成,跟进ToolbarActionBar类,可以看到ToolbarActionBar是ActionBar的子类,并且有个成员变量private DecorToolbar mDecorToolbar,
public ToolbarActionBar(Toolbar toolbar, CharSequence title, Window.Callback callback) { mDecorToolbar = new ToolbarWidgetWrapper(toolbar, false); mWindowCallback = new ToolbarCallbackWrapper(callback); mDecorToolbar.setWindowCallback(mWindowCallback); toolbar.setOnMenuItemClickListener(mMenuClicker); mDecorToolbar.setWindowTitle(title); }
在以上的代码中,toolbar作为参数完成成员变量mDecorToolbar的初始化。并在以下的代码中得到Toolbar的属性。
public ToolbarWidgetWrapper(Toolbar toolbar, boolean style, int defaultNavigationContentDescription, int defaultNavigationIcon) { mToolbar = toolbar; mTitle = toolbar.getTitle(); mSubtitle = toolbar.getSubtitle(); mTitleSet = mTitle != null; mNavIcon = toolbar.getNavigationIcon(); if (style) { final TintTypedArray a = TintTypedArray.obtainStyledAttributes(toolbar.getContext(), null, R.styleable.ActionBar, R.attr.actionBarStyle, 0); final CharSequence title = a.getText(R.styleable.ActionBar_title); if (!TextUtils.isEmpty(title)) { setTitle(title); } final CharSequence subtitle = a.getText(R.styleable.ActionBar_subtitle); if (!TextUtils.isEmpty(subtitle)) { setSubtitle(subtitle); } final Drawable logo = a.getDrawable(R.styleable.ActionBar_logo); if (logo != null) { setLogo(logo); } final Drawable icon = a.getDrawable(R.styleable.ActionBar_icon); if (mNavIcon == null && icon != null) { setIcon(icon); } final Drawable navIcon = a.getDrawable(R.styleable.ActionBar_homeAsUpIndicator); if (navIcon != null) { setNavigationIcon(navIcon); } setDisplayOptions(a.getInt(R.styleable.ActionBar_displayOptions, 0)); final int customNavId = a.getResourceId( R.styleable.ActionBar_customNavigationLayout, 0); if (customNavId != 0) { setCustomView(LayoutInflater.from(mToolbar.getContext()).inflate(customNavId, mToolbar, false)); setDisplayOptions(mDisplayOpts | ActionBar.DISPLAY_SHOW_CUSTOM); } final int height = a.getLayoutDimension(R.styleable.ActionBar_height, 0); if (height > 0) { final ViewGroup.LayoutParams lp = mToolbar.getLayoutParams(); lp.height = height; mToolbar.setLayoutParams(lp); } final int contentInsetStart = a.getDimensionPixelOffset( R.styleable.ActionBar_contentInsetStart, -1); final int contentInsetEnd = a.getDimensionPixelOffset( R.styleable.ActionBar_contentInsetEnd, -1); if (contentInsetStart >= 0 || contentInsetEnd >= 0) { mToolbar.setContentInsetsRelative(Math.max(contentInsetStart, 0), Math.max(contentInsetEnd, 0)); } final int titleTextStyle = a.getResourceId(R.styleable.ActionBar_titleTextStyle, 0); if (titleTextStyle != 0) { mToolbar.setTitleTextAppearance(mToolbar.getContext(), titleTextStyle); } final int subtitleTextStyle = a.getResourceId( R.styleable.ActionBar_subtitleTextStyle, 0); if (subtitleTextStyle != 0) { mToolbar.setSubtitleTextAppearance(mToolbar.getContext(), subtitleTextStyle); } final int popupTheme = a.getResourceId(R.styleable.ActionBar_popupTheme, 0); if (popupTheme != 0) { mToolbar.setPopupTheme(popupTheme); } a.recycle(); // Keep the TintManager in case we need it later mTintManager = a.getTintManager(); } else { mDisplayOpts = detectDisplayOptions(); // Create a TintManager in case we need it later mTintManager = TintManager.get(toolbar.getContext()); } setDefaultNavigationContentDescription(defaultNavigationContentDescription); mHomeDescription = mToolbar.getNavigationContentDescription(); setDefaultNavigationIcon(mTintManager.getDrawable(defaultNavigationIcon)); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { final ActionMenuItem mNavItem = new ActionMenuItem(mToolbar.getContext(), 0, android.R.id.home, 0, 0, mTitle); @Override public void onClick(View v) { if (mWindowCallback != null && mMenuPrepared) { mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mNavItem); } } }); }
由于Toolbar最后还是设置给了ActionBar,因此在v7包中,通过Activity的对象activity.getSupportActionBar()方法取得的ActionBar对象是能够正常使用并修改ActionBar属性的。
- Toolbar使用说明
- GTK+中工具栏(Toolbar)使用说明
- ToolBar
- ToolBar
- TOOLBAR
- ToolBar
- ToolBar
- toolbar
- ToolBar
- Toolbar
- Toolbar
- ToolBar
- ToolBar
- Toolbar
- toolbar
- ToolBar
- Toolbar
- Toolbar
- 利用 rsync 在服务器间同步目录
- 优秀开源代码解读之JS与iOS Native Code互调的优雅实现方案
- EJB到底是什么,真的那么神秘吗??
- PagerAdapter
- Android 中部分文字高亮显示方法
- Toolbar使用说明
- Spring进阶之路(9)-Spring AOP面向切面编程概念以及通过JDK代理生成AOP代理对象
- spark sql 1.6.0 自定义永久函数
- 可执行文件中和动态链接有关的段section
- leetcode 60. Permutation Sequence
- CodeForces 630L:Cracking the Code【数论】
- 元素的排序
- 抽象数据类型的定义
- 【BZOJ2038】小Z的袜子,第一次的莫队算法