前言
Android开发必不可少的就是和Toolbar打交道,毕竟它可以在标题栏自定义很多东西。之前做项目的时候一直想怎么把toolbar封装起来。最开始的做法是写一个含有toolbar的布局,然后在activity的布局里面include进去。但是这样每次写一个页面的时候都要实例一次这玩意。(虽然它是可以自定义内容,但是项目的页面toolbar一般都是大同小异的,只有少部分页面出现多一个按钮,少一个图标的情况。而每次写activity的时候都要重复写那几行代码实在不科学!)后来在网上看到了一种方法:将toolbar封在BaseActivity中,以后写代码就一劳永逸了。
编写一个toolbar的布局
<FrameLayout 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:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
android:id="@+id/id_tool_bar"
android:background="@color/action_bar_color"
app:titleTextColor="@color/doument_white"
app:subtitleTextColor="@color/doument_white"
app:titleMarginStart="15dp"
android:elevation="15dp"
>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:textColor="@color/doument_white"
android:textSize="18dp"/>
</android.support.v7.widget.Toolbar>
</FrameLayout>
这里的东西都可以自定义的,比如我自定义了两个标题的文本颜色、背景色、还有一个自定义View(用作有需要标题居中需求时使用)。如果你不想使用它自带的menu功能也可以在里面加个按钮什么的,反正toolbar是一个ViewGroup只要考虑布局就好。
一个toolbar的帮助类
public class ToolBarHelper {
/*上下文,创建view的时候须要用到*/
private Context mContext;
/*base view*/
private FrameLayout mContentView;
/*用户定义的view*/
private View mUserView;
/*toolbar*/
private Toolbar mToolBar;
/*视图构造器*/
private LayoutInflater mInflater;
/*自定义title*/
private TextView mTitle;
/*
* 两个属性
* 1、toolbar是否悬浮在窗体之上
* 2、toolbar的高度获取
* */
private static int[] ATTRS = {
R.attr.windowActionBarOverlay,
R.attr.actionBarSize
};
public ToolBarHelper(Context context, int layoutId) {
this.mContext = context;
mInflater = LayoutInflater.from(mContext);
/*初始化整个内容*/
initContentView();
/*初始化用户定义的布局*/
initUserView(layoutId);
/*初始化toolbar*/
initToolBar();
}
private void initContentView() {
/*直接创建一个帧布局,作为视图容器的父容器*/
mContentView = new FrameLayout(mContext);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
mContentView.setLayoutParams(params);
}
private void initToolBar() {
/*通过inflater获取toolbar的布局文件*/
View toolbar = mInflater.inflate(R.layout.toolbar_common, mContentView);
mToolBar = (Toolbar) toolbar.findViewById(R.id.id_tool_bar);
mTitle=(TextView) toolbar.findViewById(R.id.title);
}
private void initUserView(int id) {
mUserView = mInflater.inflate(id, null);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
TypedArray typedArray = mContext.getTheme().obtainStyledAttributes(ATTRS);
/*获取主题中定义的悬浮标志*/
boolean overly = typedArray.getBoolean(0, false);
/*获取主题中定义的toolbar的高度*/
@SuppressLint("ResourceType") int toolBarSize = (int) typedArray.getDimension(1,(int) mContext.getResources().getDimension(R.dimen.abc_action_bar_default_height_material));
typedArray.recycle();
/*假设是悬浮状态,则不须要设置间距*/
params.topMargin = overly ? 0 : toolBarSize;
mContentView.addView(mUserView, params);
}
public FrameLayout getContentView() {
return mContentView;
}
public Toolbar getToolBar() {
return mToolBar;
}
/*********************外部方法******************************/
public ToolBarHelper setTitle(String title){
mToolBar.setTitle(title);
return this;
}
public ToolBarHelper setTitle(int resId){
mToolBar.setTitle(resId);
return this;
}
public ToolBarHelper setSubtitle(String subTitle){
mToolBar.setSubtitle(subTitle);
return this;
}
public ToolBarHelper setSubtitle(int resId){
mToolBar.setSubtitle(resId);
return this;
}
public ToolBarHelper setNavigationIcon(Drawable drawable) {
mToolBar.setNavigationIcon(drawable);
return this;
}
public ToolBarHelper setNavigationIcon(int resId) {
mToolBar.setNavigationIcon(resId);
return this;
}
public ToolBarHelper setLogo(int resId){
mToolBar.setLogo(resId);
return this;
}
public ToolBarHelper setCustomTitle(String title){
mTitle.setVisibility(View.VISIBLE);
mTitle.setText(title);
return this;
}
public ToolBarHelper setCustomTitle(int resId){
mTitle.setVisibility(View.VISIBLE);
mTitle.setText(mContext.getText(resId));
return this;
}
}
这个帮助类通过外部activity传入的布局调节这整个布局的上边距 margin_top,来适配加入toolbar之后的页面样式。然后通过上面写的toolbar的布局实例化toolbar也包括里面包含的自定义view(这里可以按实际情况进行修改)。同时我也自定义了一些外部方法,调用这些方法来设置title、icon之类的属性。可以按实际需要进行添加。
在BaseActivity中操作该帮助类
首先定义toolbar和toolbarHelper的对象
public ToolBarHelper mToolBarHelper ;
private Toolbar toolbar ;
ToolBarHelper定义的是public的,方便子类通过它来调用上述写的一些外部方法。
然后是重写activity的setContentView方法
@Override
public void setContentView(int layoutResID) {
mToolBarHelper = new ToolBarHelper(this,layoutResID) ;
toolbar = mToolBarHelper.getToolBar() ;
setContentView(mToolBarHelper.getContentView());
/*把 toolbar 设置到Activity 中*/
setSupportActionBar(toolbar);
/*自己定义的一些操作*/
onCreateCustomToolBar(toolbar) ;
}
将activity布局的id传给toolBarHelper,生成对应的布局和toolbar后再重新设置到activity中显示。然后onCreateCustomToolBar(toolbar) 这个方法是用作写一些toolbar的相关设置的。比如可以写一些以前关于toolbar重复较高的代码
public void onCreateCustomToolBar(Toolbar toolbar){
toolbar.setContentInsetsRelative(0,0);
getSupportActionBar().setDisplayShowTitleEnabled(false); //设置隐藏应用名
toolbar.setNavigationOnClickListener(new View.OnClickListener() { //默认点击事件
@Override
public void onClick(View v) {
finish();
}
});
}
注:上面的setNavigationOnClickListener如果有特殊需要的话在子类中将toolbar通过toolbarHelper的get方法拿出来然后重写监听就可以了。其他方法重写类似
最后
说实话,这个封装解决了我这么久对于toolbar的代码强迫症,个人感觉还是比较实用的。
最后贴一张山寨微信的图,比上次好看了一点。这个也是我用封装的toolbar写的!
