ProgressFragment的簡單封裝

寫在前面

一般我們開發(fā)應(yīng)用的時候弃锐,比如首頁或者詳情界面,當(dāng)請求數(shù)據(jù)的時候挖炬,我們一般都會給用戶一個簡單的提示讯壶,比如加一個進(jìn)度條或者彈出一個Dialog料仗。但是有時候彈出Dialog的時候只是給用戶了一個提示,但是當(dāng)出現(xiàn)錯誤之后伏蚊,也只是簡單的一個Toast提示罢维,并不能再次進(jìn)行請求(有可能稍微做些處理,比如請求錯誤之后隱藏content布局然后在顯示一個錯誤布局)丙挽,第一種情況體驗很是糟糕,第二種情況稍微好點(diǎn)匀借,但是我們每次寫一個布局都需要多寫錯誤布局(或者寫一個公共的颜阐,然后在其他地方進(jìn)行引用,但是有一點(diǎn)就是我們在每次的activity或者fragment使用的時候都需要寫入邏輯)吓肋,造成不必要的代碼冗余凳怨。今天就來進(jìn)行封裝一下,完成一個侵入式的ProgressFragment是鬼。

開始實現(xiàn)

第一步分析

我們首先要實現(xiàn)的封裝肤舞,能夠達(dá)到以下的幾個要求

  • 1、加載的時候顯示Loading狀態(tài)
  • 2均蜜、數(shù)據(jù)為空或者錯誤的時候顯示數(shù)據(jù)為錯誤或者其他提示
  • 3李剖、正常情況顯示正常數(shù)據(jù)狀態(tài)
  • 4、當(dāng)“數(shù)據(jù)為空或者錯誤狀態(tài)”的時候囤耳,可以點(diǎn)擊進(jìn)行重新請求數(shù)據(jù)

原理分析

看到那四個需要實現(xiàn)的條件篙顺,我們大致可以了解到,需要有三種布局狀態(tài)正常布局狀態(tài)充择、錯誤布局狀態(tài)德玫、Loading狀態(tài)有了這幾種狀態(tài),我們就可以在請求的時候根據(jù)我們定義的以下方法(或者類似方法),然后控制不同布局的顯示和加載

  • showLoading()方法中顯示Loading狀態(tài)布局
  • showError()或者showNoData()方法顯示錯誤狀態(tài)布局
  • 其余正常狀態(tài)顯示正常布局狀態(tài)(也就是剛開始這個布局是顯示visiable)

代碼實現(xiàn)

有了分析椎麦,我們首先可以知道需要三種布局(錯誤宰僧、加載、正常)

錯誤布局

 <LinearLayout
        android:id="@+id/view_empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:visibility="gone">

        <TextView
            android:id="@+id/text_tip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/empty_data"/>
    </LinearLayout>

加載布局

  <LinearLayout
        android:id="@+id/view_progress"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="vertical"
        android:visibility="gone">


        <ProgressBar
            android:id="@+id/progress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

        <TextView
            android:id="@+id/text_loading"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="@string/loading"/>

    </LinearLayout>

正常布局

 <FrameLayout
        android:id="@+id/view_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </FrameLayout>

布局完成之后观挎,首先說明一下琴儿,他們?nèi)齻€的頂層布局是FrameLayout(ViewGroup的子類)
然后看下邏輯代碼怎么實現(xiàn)的吧段化。

第一步就是找到布局id
 @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //跟布局
        mRootView = (FrameLayout) inflater.inflate(R.layout.fragment_progress, container, false);
        //空布局也就是錯誤布局
        mViewEmpty = mRootView.findViewById(R.id.view_empty);
        //對錯誤布局實現(xiàn)點(diǎn)擊事件  完成加載出錯或者數(shù)據(jù)為空的時候  點(diǎn)擊重新請求數(shù)據(jù)邏輯
        mViewEmpty.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onEmptyViewClick();
            }
        });
        //加載loading布局
        mViewProgress = mRootView.findViewById(R.id.view_progress);
        //真實的布局
        mViewContent = (FrameLayout) mRootView.findViewById(R.id.view_content);
        //加載出錯或者數(shù)據(jù)為空顯示的錯誤布局的一個提示
        mEmptyTextView = (TextView) mRootView.findViewById(R.id.text_tip);
        return mRootView;
    }
第二步確定什么時候加載真實布局
  @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        this.mApplication = (CNMarketApplication) getActivity().getApplication();
        setupAcitivtyComponent(mApplication.getAppComponent());
        //加載真實的布局
        setRealContentView();
        //用于初始化布局控件  這里也可以不寫  因為我們使用了ButterKnife實現(xiàn)對控件的注解
        init();
        //用于子類實現(xiàn)  請求數(shù)據(jù)方法
        initData();
    }

setRealContentView()方法

 /**
     * 設(shè)置真正的布局
     */
    private void setRealContentView() {
        View realContentView = LayoutInflater.from(getActivity()).inflate(setLayout(), mViewContent, true);
        mUnbinder = ButterKnife.bind(this, realContentView);
    }
第三步控制三種布局的顯示

我們這個時候要寫控制三種布局的顯示和隱藏的邏輯,這個時候可能有人會這樣寫

    /**
     * 顯示加載loading布局
     */
    public void showProgressView(){
        mViewProgress.setVisibility(View.VISIBLE);
        mViewEmpty.setVisibility(View.GONE);
        mViewContent.setVisibility(View.GONE);
    }

然后在寫剩余的兩種邏輯凤类,這樣寫沒有錯穗泵,但是感覺代碼是有點(diǎn)冗余而且也不太好看,前面我們提到過谜疤,跟布局是一個FrameLayout佃延,屬于ViewGroup的子類,那么他就有getChildCount()方法獲取子view那么我們就可以這樣寫邏輯了夷磕。

  /**
     * 判斷要顯示的子view  正常布局  錯誤布局  loading布局  根據(jù)傳入的viewId
     *
     * @param viewId 需要顯示的viewid
     */
    public void showView(int viewId) {
        int childCount = mRootView.getChildCount();
        for (int i = 0; i < childCount; i++) {
            if (mRootView.getChildAt(i).getId() == viewId) {
                mRootView.getChildAt(i).setVisibility(View.VISIBLE);
            } else {
                mRootView.getChildAt(i).setVisibility(View.GONE);  //隱藏
            }
        }
    }

然后接下來這樣寫三個邏輯


    /**
     * 顯示進(jìn)度條view
     */
    public void showProgressView() {
        showView(R.id.view_progress);
    }

    /**
     * 顯示真實布局view
     */
    public void showContentView() {
        showView(R.id.view_content);
    }

    /**
     * 顯示數(shù)據(jù)為空view
     */
    public void showEmptyView() {
        showView(R.id.view_empty);
    }

    /**
     * 顯示數(shù)據(jù)為空view
     */
    public void showEmptyView(int resId) {

        showView(R.id.view_empty);
        mEmptyTextView.setVisibility(View.VISIBLE);
        mEmptyTextView.setText(resId);
    }

    /**
     * 顯示數(shù)據(jù)為空view
     */
    public void showEmptyView(String msgId) {
        showView(R.id.view_empty);
        mEmptyTextView.setVisibility(View.VISIBLE);
        mEmptyTextView.setText(msgId);
    }

第四步子類使用

這個時候基本邏輯就差不多完事了履肃,然后剩余的就需要子Fragment或者子activity進(jìn)行繼承和重寫方法,實現(xiàn)邏輯了坐桩。比如

重新請求數(shù)據(jù)

    @Override
    public void onEmptyViewClick() {
        super.onEmptyViewClick();
        //重新請求數(shù)據(jù)
        mPresenter.requestDatas();
    }

顯示錯誤和數(shù)據(jù)為空邏輯

@Override
    public void showNoData() {
        //showError("沒有數(shù)據(jù)進(jìn)行展示");
        showEmptyView("沒有數(shù)據(jù)進(jìn)行展示");
        Toast.makeText(getActivity(), "沒有數(shù)據(jù)進(jìn)行展示", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showError(String msg) {
       // showError(msg);
        showEmptyView(msg);
        Toast.makeText(getActivity(), "服務(wù)器開小差了" + msg, Toast.LENGTH_SHORT).show();
    }

這里整體邏輯就算實現(xiàn)了尺棋,完整的代碼我就不貼了,這里直接給出git地址

*一個集RxJava+Retrofit+MVP+Dagger2的app

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末膘螟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子碾局,更是在濱河造成了極大的恐慌荆残,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件净当,死亡現(xiàn)場離奇詭異内斯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)像啼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門俘闯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人忽冻,你說我怎么就攤上這事真朗。” “怎么了僧诚?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵蜜猾,是天一觀的道長。 經(jīng)常有香客問我振诬,道長蹭睡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任赶么,我火速辦了婚禮肩豁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己清钥,他們只是感情好琼锋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著祟昭,像睡著了一般缕坎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上篡悟,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天谜叹,我揣著相機(jī)與錄音,去河邊找鬼搬葬。 笑死荷腊,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的急凰。 我是一名探鬼主播女仰,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼抡锈!你這毒婦竟也來了疾忍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤床三,失蹤者是張志新(化名)和其女友劉穎锭碳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體勿璃,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年推汽,在試婚紗的時候發(fā)現(xiàn)自己被綠了补疑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡歹撒,死狀恐怖莲组,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情暖夭,我是刑警寧澤锹杈,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站迈着,受9級特大地震影響竭望,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜裕菠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一咬清、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦旧烧、人聲如沸影钉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽平委。三九已至,卻和暖如春夺谁,著一層夾襖步出監(jiān)牢的瞬間廉赔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工予权, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留昂勉,地道東北人。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓扫腺,卻偏偏與公主長得像岗照,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子笆环,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,116評論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫攒至、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,103評論 4 62
  • 花明柳岸濟(jì)孺蒙 繾綣胡風(fēng)曳碧穹 決眥青林傾雨寂 掠花疏影捻春紅 曉乘輕楫穿吳越 暮謝香車宿戶蓬 把酒還來相虐笑 閑...
    宏波_閱讀 314評論 1 4
  • 但耶穌的名聲越發(fā)傳揚(yáng)出去躁劣。有極多的人聚集來聽道迫吐,也指望醫(yī)治他們的病。耶穌卻退到曠野去禱告账忘。 在名聲傳揚(yáng)出去志膀,跟隨聚...
    YNC再寫一篇閱讀 97評論 0 0
  • 在婚姻里有相同價值觀的伴侶溉浙,彼此能談得來,能夠相互幫助蒋荚、尊重戳稽、欣賞、共同成長期升,這樣的婚姻會更長久...
    飄香有約閱讀 250評論 2 1