Builder设计模式 - 构建整个应用的NavigationBar

1. 概述

每个项目都必须处理头部部分,刚刚开始我们都是在activity布局文件中写一个布局然后findViewById去操作。渐渐的我们开始自定义View然后把自定义的头部写入布局文件中几下就可以解决头部的问题,并且也不用担心应用版本升级换风格问题。有人说我是用的ToolBar和ActionBar,我想说的是这些也是自定义View你看看源码就知道,只不过是google给我们的自定义好了,总之这些处理都需要写在布局文件中且随着版本升级扩展性并不是特别高。
  这一期我们来看一下如何利用Builder设计模式构建整个应用的NavigationBar,再也不必在activity中写任何布局,而且一行解决头部的问题。前提是你必须得了解Builder设计模式和泛型,泛型这是基础大家可以去看看别人写的文章,至于Builder设计模式我上一期就讲了Android Builder设计模式 – 构建整个项目的万能Dialog可以先去看看这里,下面我就直接开始写了。

视频地址:http://pan.baidu.com/s/1dFuv96p

相关文章:

2017Android进阶之路与你同行

Builder设计模式 – 构建整个项目的万能Dialog
  
  Builder设计模式 – 构建整个应用的NavigationBar

2. 实现

2.1 定义导航条规范

**
 * description:定义导航条规范
 *
 * Created by 曾辉 on 2016/6/30 22:35
 * QQ:240336124
 * Email: 240336124@qq.com
 * Version:1.0
 */
public interface INavigation {

    // 绑定布局ID
    public int bindLayoutId();

    // 给View设置参数
    public void applyView();
}

2.2 构建AbsNavigationBar

为了良好的扩展性,我们首先构建一个最基础的导航栏,直接就写最终效果的哥们我只想说你可能永远不了解产品的心里,为了以后我们不去骂娘,我们自己得先去想好退路。

 /**
 * description:添加默认的配置
 * <p>
 * Created by 曾辉 on 2016/6/30 22:35
 * QQ:240336124
 * Email: 240336124@qq.com
 * Version:1.0
 */
public abstract class AbsNavigationBar<P extends AbsNavigationBar.Builder.NavigationParams> implements INavigation {

    private P params;

    private View view;

    public AbsNavigationBar(P params) {
        this.params = params;
        createAndBind();
    }

    protected String getString(int id) {
        return this.params.context.getResources().getString(id);
    }

    protected int getColor(int id) {
        return ContextCompat.getColor(this.params.context, id);
    }

    protected P getParams() {
        return params;
    }


    /**
     * 设置文本
     * @param viewId
     * @param text
     */
    protected void setText(int viewId, CharSequence text) {
        TextView tv = findViewById(viewId);
        if (tv != null) {
            tv.setText(text);
        }
    }

    /**
     * 设置点击事件
     * @param viewId
     * @param listener
     */
    protected void setOnClickListener(int viewId, View.OnClickListener listener) {
        View view = findViewById(viewId);
        if (view != null) {
            view.setOnClickListener(listener);
        }
    }


    /**
     * 设置背景资源
     * @param viewId
     * @param resourceId
     */
    protected void setImageResource(int viewId, int resourceId) {
        ImageView imageView = findViewById(viewId);
        if (imageView != null) {
            imageView.setImageResource(resourceId);
        }
    }

    protected <T extends View> T findViewById(int id) {
        return (T) view.findViewById(id);
    }


    /**
     * 创建和绑定布局
     */
    public void createAndBind() {
        if (params == null) {
            return;
        }
        view = LayoutInflater.from(params.context).inflate(bindLayoutId(), params.parent, false);
        params.parent.addView(view, 0);
        applyView();
    }


    // 构建导航条类 这个类只是定义默认的配置 具体功能的实现一定由具体的实现类决定
    public abstract static class Builder {

        // 构建导航条方法
        public abstract AbsNavigation create();

        // 默认的配置参数
        public static class NavigationParams {
            public Context context;
            public ViewGroup parent;

            public NavigationParams(Context context, ViewGroup parent) {
                this.context = context;
                this.parent = parent;
            }
        }
    }
}

2.2 构建DefaultNavigationBar

我们构建好一个默认通用的NavigationBar去适配98%的效果,至于那些特别奇葩的可以自己去想办法,可以写到布局文件中,也可以自己去定义奇葩NavigationBar只要继承AbsNavigation也是很简单的事,这里我就写一个内涵段子通用的导航栏。

/**
 * description: 内涵段子默认导航栏
 * <p>
 * Created by 曾辉 on 2016/6/30 22:35
 * QQ:240336124
 * Email: 240336124@qq.com
 * Version:1.0
 */
public class DefaultNavigation<D extends AbsNavigation.Builder.NavigationParams> extends
        AbsNavigation<DefaultNavigation.Builder.DefaultNavigationParams> {
    public DefaultNavigation(Builder.DefaultNavigationParams params) {
        super(params);
    }

    @Override
    public void applyView() {
        // 给我们的导航条绑定资源
        setImageResource(R.id.iv_left, getParams().leftIconRes);
        setImageResource(R.id.iv_right, getParams().rightIconRes);
        setImageResource(R.id.iv_right_icon, getParams().textRightIconRes);
        setText(R.id.title_tv, getParams().title);
        setText(R.id.left_tv, getParams().leftTv);
        setText(R.id.right_tv, getParams().rightTv);
        setBackgroundColor(R.id.title_bar, getParams().bgColor);
        setOnClickListener(R.id.left_ll, getParams().leftOnClickListener);
        setOnClickListener(R.id.right_ll, getParams().rightOnClickListener);
    }

    @Override
    public int bindLayoutId() {
        // 绑定布局layoutId
        return R.layout.navigation_default;
    }

    // 构建导航条类
    public static class Builder extends AbsNavigation.Builder {
        private DefaultNavigationParams params;

        public Builder(Context context, ViewGroup parent) {
            params = new DefaultNavigationParams(context, parent);
        }

        public Builder setTitle(String title) {
            params.title = title;
            return this;
        }

        public Builder setRight(String right) {
            params.rightTv = right;
            return this;
        }

        public Builder setLeft(String left) {
            params.leftTv = left;
            return this;
        }

        public Builder setLeftIcon(int iconRes) {
            params.leftIconRes = iconRes;
            return this;
        }

        public Builder setRightIcon(int iconRes) {
            params.rightIconRes = iconRes;
            return this;
        }

        public Builder setTitleBackgroundColor(int bgColor) {
            params.bgColor = bgColor;
            return this;
        }

        public Builder setLeftOnClickListener(View.OnClickListener onClickListener) {
            params.leftOnClickListener = onClickListener;
            return this;
        }

        public Builder setRightOnClickListener(View.OnClickListener onClickListener) {
            params.rightOnClickListener = onClickListener;
            return this;
        }

        @Override
        public DefaultNavigation<NavigationParams> create() {
            DefaultNavigation<NavigationParams> navigation = new DefaultNavigation<NavigationParams>(params);
            return navigation;
        }

        // 默认的配置参数
        public static class DefaultNavigationParams extends NavigationParams {
            //标题
            public String title;
            //左边图片资源
            public int leftIconRes;
            //右边图片资源
            public int rightIconRes;
            //左边的点击事件
            public View.OnClickListener leftOnClickListener;
            //右边的点击事件
            public View.OnClickListener rightOnClickListener;
            public String leftTv;
            public String rightTv;
            public int bgColor;

            public DefaultNavigationParams(Context context, ViewGroup parent) {
                super(context, parent);
            }
        }
    }
}

3. 见证奇迹的时刻

以后我们再也不必老老实实在activity布居中屁颠屁颠的去写了,只需要在Activity代码中写短短的写一行代码就可以了:

    DefaultNavigationBar navigationBar = new DefaultNavigation.Builder(this,
                (ViewGroup) findViewById(android.R.id.content))
                .setLeftIcon(R.drawable.common_back).setTitle("投稿").setRightText("发表").create();

以后再写头部这样子写就可以了,当然如果还是坚持findViewById的方式去操作我也不强人所难。后面的再讲设计模式的时候可能就不会单独讲了,而是好几种嵌套因为后面的内容越来越难了,大家做好准备之前的内容没消化的赶紧消化最主要的还是要自己去敲,最近有收到很多哥们的感谢信我真的会一直坚持下去的,视频还是老套路只能等周末晚上。

视频地址:http://pan.baidu.com/s/1dFuv96p

相关文章:

2017Android进阶之路与你同行

Android Builder设计模式 – 构建整个项目的万能Dialog

Builder设计模式 – 构建整个应用的NavigationBar

    原文作者:红橙Darren
    原文地址: https://www.jianshu.com/p/570d8bddb5c0
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞