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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容