Builder设计模式构建整个应用的头部(NavigationBar)

开发中基本上每个APP都会有自己的头部,如何去写这个头部呢?一部分人会在xml布局中直接写,一部分人会调用系统的ToolBar自定义布局,这两种方式都可以去实现,但是有个问题,如果产品频繁让你改这个头部你会不会崩溃呢?
A : “我自己写的,我都清楚哪个控件是什么,有什么用,改一下也不费事”
B : "慢慢捋还是可以改的";
我想说 既然每个应用都能用到这个头部 为什么不能进一步封装一下呢?一句代码搞定的事没有必要写很多行。
这一期我们来看一下如何利用Builder设计模式构建整个应用的NavigationBar,再也不必在activity中写任何布局,而且一行解决头部的问题。

  • 首选看一下我们要写的NavigationBar的结构图


    NavationBar结构图.png

通过图可以知道,首先先写个接口用来规范头部,然后写个abstract基类,再写一个DefaultNavigationBar去实现这个抽象类,特殊情况特殊对待吧。
1.定义头部规范接口

/**
 * 导航栏规范
 */
public interface INavigation {
    //绑定头部ID
    public int bindLayoutId();
    //绑定头部参数
    public void applyView();
}

2.创建一个基类AbsNavigationBar
在创建前先稍微讲一下builder设计模式的构造 看图。


build模式结构图.png
/**
 * Created by LiMing on 2018/4/24.
 * QQ:1002464056
 * Email: [email protected]
 * Version:1.0
 * 基类(所有的在此基础上写)
 */

public abstract class AbsNavigationBar

implements INavigation { private P mParmas; private View mNavigationView; public AbsNavigationBar(P parmas){ this.mParmas=parmas; creatAndBind(); } public P getmParmas() { return mParmas; } //创建和绑定视图 private void creatAndBind() { if (mParmas.mParent==null) { //获取根布局 ViewGroup viewGroup = ((Activity) mParmas.mContext).findViewById(android.R.id.content); // 将根布局中第一个视图作为父容器(linearLayout) mParmas.mParent= (ViewGroup) viewGroup.getChildAt(0); } if (mParmas.mParent==null) { return; } //创建头部视图 mNavigationView= LayoutInflater.from(mParmas.mContext).inflate(R.layout.title_bar,mParmas.mParent,false); //将头部视图添加到父容器中 mParmas.mParent.addView(mNavigationView,0); //调用设置参数的方法 applyView(); } public abstract static class Build{ public Build (Context context,ViewGroup parent){} // 创建一个 AbsNavigationBar public abstract AbsNavigationBar builder(); public static class AbsNavigationBarParmas{ public Context mContext; public ViewGroup mParent; public AbsNavigationBarParmas(Context context,ViewGroup parent){ this.mContext=context; this.mParent=parent; } } } }

3.实现类 DefaultNavigationBar 实现基类,然后在此基础上添加设置,如修改文字,设置监听之类的


/**
 * Created by LiMing on 2018/4/24.
 * QQ:1002464056
 * Email: [email protected]
 * Version:1.0
 */

public class DefaultNavigationBar extends AbsNavigationBar {



    public DefaultNavigationBar(DefaultNavigationBar.Build.DefaultNavigationBarParmas parmas) {
        super(parmas);
    }

    @Override
    public int bindLayoutId() {
        return R.layout.title_bar;
    }

    @Override
    public void applyView() {
        //实现设置的参数
        //设置标题
        setText(R.id.title,getmParmas().mTitle);
        //设置左边文字
        setText(R.id.left_text,getmParmas().leftText);
        // 设置左边图片的点击事件
        setOnClickListener(R.id.back,getmParmas().leftClickListener);
    }




    public static class Build extends AbsNavigationBar.Build{

        DefaultNavigationBarParmas p;
        public Build(Context context, ViewGroup parent) {
            super(context, parent);
            //创建DefaultNavigationBarParma 对象
            p=new DefaultNavigationBarParmas(context,parent);
        }
        public Build(Context context) {
            super(context, null);
            p=new DefaultNavigationBarParmas(context,null);
        }

        @Override
        public DefaultNavigationBar builder() {

            DefaultNavigationBar defaultNavigationBar=new DefaultNavigationBar(p);
            return defaultNavigationBar;
        }
        // 1.设置参数

        /**
         * 设置title
         * @param title
         * @return
         */
        public DefaultNavigationBar.Build setTitle(String title){
            p.mTitle=title;
            return this;
        }

        /**
         * 设置左边的文字
         * @param leftText
         * @return
         */
        public DefaultNavigationBar.Build setLeftText(String leftText){
            p.leftText=leftText;
            return this;
        }

        /**
         * 设置左边图片监听
         * @param clickListener
         * @return
         */
        public DefaultNavigationBar.Build setLeftImageClickListener(View.OnClickListener clickListener){
            p.leftClickListener=clickListener;
            return this;
        }

        public class DefaultNavigationBarParmas extends AbsNavigationBarParmas{

            //2.参数存放的位置
            public String mTitle;
            public String leftText;
            public View.OnClickListener leftClickListener;
            public DefaultNavigationBarParmas(Context context, ViewGroup parent) {
                super(context, parent);
            }
        }

    }
}

通用的80%的功能在此基本可以实现,我只是写了几个方法,有需要的要继续完善,剩下的特殊的20%的功能需要自己去实现了。
具体怎么调用呢?很简单的,一句代码搞定!


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DefaultNavigationBar defaultNavigationBar= new DefaultNavigationBar.Build(this)
                                                    .setTitle("导航栏")
                                                    .setLeftText("返回").setLeftImageClickListener(new View.OnClickListener() {
                                                            @Override
                                                            public void onClick(View view) {
                                                                Toast.makeText(MainActivity.this, "点击了返回按钮", Toast.LENGTH_SHORT).show();
                                                            }
                                                        })
                                                    .builder();
    }
}

好了,以后不用再为修改头部烦恼了,一句代码搞定,觉得实用呢就试着用用~~

受辉哥的影响,学习了不少,大家可以去他的博客看看,很实用 @红橙Darren

你可能感兴趣的:(Builder设计模式构建整个应用的头部(NavigationBar))