前言

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写的!
screenshot-1525441150794.jpg

标签: none

添加新评论