Builder設(shè)計模式 - 構(gòu)建整個應(yīng)用的NavigationBar

1. 概述


每個項目都必須處理頭部部分,剛剛開始我們都是在activity布局文件中寫一個布局然后findViewById去操作罐韩。漸漸的我們開始自定義View然后把自定義的頭部寫入布局文件中幾下就可以解決頭部的問題甚脉,并且也不用擔(dān)心應(yīng)用版本升級換風(fēng)格問題滚澜。有人說我是用的ToolBar和ActionBar蓉媳,我想說的是這些也是自定義View你看看源碼就知道八酒,只不過是google給我們的自定義好了空民,總之這些處理都需要寫在布局文件中且隨著版本升級擴展性并不是特別高。
  這一期我們來看一下如何利用Builder設(shè)計模式構(gòu)建整個應(yīng)用的NavigationBar羞迷,再也不必在activity中寫任何布局界轩,而且一行解決頭部的問題。前提是你必須得了解Builder設(shè)計模式和泛型衔瓮,泛型這是基礎(chǔ)大家可以去看看別人寫的文章浊猾,至于Builder設(shè)計模式我上一期就講了Android Builder設(shè)計模式 - 構(gòu)建整個項目的萬能Dialog可以先去看看這里,下面我就直接開始寫了热鞍。

視頻地址:http://pan.baidu.com/s/1dFuv96p

相關(guān)文章:

2017Android進階之路與你同行

Builder設(shè)計模式 - 構(gòu)建整個項目的萬能Dialog
  
  Builder設(shè)計模式 - 構(gòu)建整個應(yīng)用的NavigationBar

2. 實現(xiàn)


2.1 定義導(dǎo)航條規(guī)范

**
 * description:定義導(dǎo)航條規(guī)范
 *
 * 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設(shè)置參數(shù)
    public void applyView();
}

2.2 構(gòu)建AbsNavigationBar

為了良好的擴展性葫慎,我們首先構(gòu)建一個最基礎(chǔ)的導(dǎo)航欄,直接就寫最終效果的哥們我只想說你可能永遠不了解產(chǎn)品的心里薇宠,為了以后我們不去罵娘偷办,我們自己得先去想好退路。

 /**
 * 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;
    }


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

    /**
     * 設(shè)置點擊事件
     * @param viewId
     * @param listener
     */
    protected void setOnClickListener(int viewId, View.OnClickListener listener) {
        View view = findViewById(viewId);
        if (view != null) {
            view.setOnClickListener(listener);
        }
    }


    /**
     * 設(shè)置背景資源
     * @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);
    }


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


    // 構(gòu)建導(dǎo)航條類 這個類只是定義默認的配置 具體功能的實現(xiàn)一定由具體的實現(xiàn)類決定
    public abstract static class Builder {

        // 構(gòu)建導(dǎo)航條方法
        public abstract AbsNavigation create();

        // 默認的配置參數(shù)
        public static class NavigationParams {
            public Context context;
            public ViewGroup parent;

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

2.2 構(gòu)建DefaultNavigationBar

我們構(gòu)建好一個默認通用的NavigationBar去適配98%的效果澄港,至于那些特別奇葩的可以自己去想辦法椒涯,可以寫到布局文件中,也可以自己去定義奇葩NavigationBar只要繼承AbsNavigation也是很簡單的事回梧,這里我就寫一個內(nèi)涵段子通用的導(dǎo)航欄逐工。

/**
 * description: 內(nèi)涵段子默認導(dǎo)航欄
 * <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() {
        // 給我們的導(dǎo)航條綁定資源
        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;
    }

    // 構(gòu)建導(dǎo)航條類
    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;
        }

        // 默認的配置參數(shù)
        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("發(fā)表").create();

以后再寫頭部這樣子寫就可以了漂辐,當(dāng)然如果還是堅持findViewById的方式去操作我也不強人所難。后面的再講設(shè)計模式的時候可能就不會單獨講了棕硫,而是好幾種嵌套因為后面的內(nèi)容越來越難了髓涯,大家做好準備之前的內(nèi)容沒消化的趕緊消化最主要的還是要自己去敲,最近有收到很多哥們的感謝信我真的會一直堅持下去的哈扮,視頻還是老套路只能等周末晚上纬纪。

視頻地址:http://pan.baidu.com/s/1dFuv96p

相關(guān)文章:

2017Android進階之路與你同行

Android Builder設(shè)計模式 - 構(gòu)建整個項目的萬能Dialog

Builder設(shè)計模式 - 構(gòu)建整個應(yīng)用的NavigationBar

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蚓再,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子包各,更是在濱河造成了極大的恐慌摘仅,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件问畅,死亡現(xiàn)場離奇詭異娃属,居然都是意外死亡,警方通過查閱死者的電腦和手機护姆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門矾端,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人卵皂,你說我怎么就攤上這事秩铆。” “怎么了灯变?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵殴玛,是天一觀的道長。 經(jīng)常有香客問我添祸,道長滚粟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任膝捞,我火速辦了婚禮坦刀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蔬咬。我一直安慰自己鲤遥,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布林艘。 她就那樣靜靜地躺著盖奈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狐援。 梳的紋絲不亂的頭發(fā)上钢坦,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音啥酱,去河邊找鬼爹凹。 笑死,一個胖子當(dāng)著我的面吹牛镶殷,可吹牛的內(nèi)容都是我干的禾酱。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼颤陶!你這毒婦竟也來了颗管?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤滓走,失蹤者是張志新(化名)和其女友劉穎垦江,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搅方,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡比吭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了腰懂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梗逮。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖绣溜,靈堂內(nèi)的尸體忽然破棺而出慷彤,到底是詐尸還是另有隱情,我是刑警寧澤怖喻,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布底哗,位于F島的核電站,受9級特大地震影響锚沸,放射性物質(zhì)發(fā)生泄漏跋选。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一哗蜈、第九天 我趴在偏房一處隱蔽的房頂上張望前标。 院中可真熱鬧,春花似錦距潘、人聲如沸炼列。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俭尖。三九已至,卻和暖如春洞翩,著一層夾襖步出監(jiān)牢的瞬間稽犁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工骚亿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留已亥,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓来屠,卻偏偏與公主長得像陷猫,于是被迫代替她去往敵國和親秫舌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容