android多狀態(tài)布局

app中請(qǐng)求服務(wù)器數(shù)據(jù)后進(jìn)行繪制頁(yè)面時(shí)會(huì)有多種狀態(tài),比如網(wǎng)絡(luò)請(qǐng)求過(guò)程中l(wèi)oading狀態(tài),加載出錯(cuò)狀態(tài),獲取數(shù)據(jù)發(fā)現(xiàn)數(shù)據(jù)為空狀態(tài),加載過(guò)程中網(wǎng)絡(luò)異常頁(yè)面和正常加載完畢的數(shù)據(jù)展示頁(yè)面。

一般的做法是將多個(gè)狀態(tài)封裝成自定義View,然后在每一個(gè)頁(yè)面的布局文件中引入,在加載數(shù)據(jù)時(shí)展示不同的狀態(tài)。

可以有另一種方案,通過(guò)代碼編寫(xiě)View的方式,將自定義View添加到頁(yè)面中,這樣可以避免了在每一個(gè)布局中手動(dòng)添加布局文件的麻煩,并且如果有抽出BaseActivity和BaseFragment的話,使用起來(lái)就更簡(jiǎn)單了(當(dāng)然,原先在布局文件中加入自定義View的方法也是可以在Base中抽取出成員變量的)

但是如何抽取呢?因?yàn)獒槍?duì)不同的頁(yè)面展示不同狀態(tài)的父布局是不確定的,可以采用比較簡(jiǎn)單的方式,給每一個(gè)布局的根布局添加id,然后獲取到根布局,使用addView方法將自定義View添加到布局中。不過(guò)這樣相對(duì)來(lái)說(shuō)太麻煩了一點(diǎn)。

根據(jù)頁(yè)面劃分的話,有三種情況,Activity,F(xiàn)ragment或者View

所以我們可以根據(jù)這三種情況來(lái)判斷,然后獲取到不同的根布局,然后添加不同狀態(tài)的View

if (mTarget == null) {
            throw new NullPointerException("參數(shù)不能為空");
        }
        Context context = null;
        if (mTarget instanceof Activity) {
            // 認(rèn)為 contentLayout 是 activity 的跟布局
            // 所以它的父控件就是 android.R.id.content
            context = (Activity) mTarget;
            mParentLayout = ((Activity) context).findViewById(android.R.id.content);
            mContentLayout = mParentLayout != null ? mParentLayout.getChildAt(0) : null;
        } else if (mTarget instanceof View) {
            // 有直接的父控件
            mContentLayout = (View) mTarget;
            context = ((View) mTarget).getContext();
            mParentLayout = (ViewGroup) mContentLayout.getParent();
        } else if (mTarget instanceof Fragment) {
            // 有直接的父控件
            mContentLayout = ((Fragment) mTarget).getView();
            context = ((Fragment) mTarget).getActivity();
            mParentLayout = (ViewGroup) mContentLayout.getParent();
        } else if (mTarget instanceof android.support.v4.app.Fragment) {
            // 有直接的父控件
            mContentLayout = ((android.support.v4.app.Fragment) mTarget).getView();
            context = ((android.support.v4.app.Fragment) mTarget).getActivity();
            mParentLayout = (ViewGroup) mContentLayout.getParent();
        } else {
            throw new IllegalArgumentException("參數(shù)必須為view、Fragment或者Activity類型");
        }

還有一個(gè)問(wèn)題就是默認(rèn)狀態(tài)布局和自定義布局的設(shè)置,因?yàn)橐粋€(gè)app包含的很多頁(yè)面不可能所有頁(yè)面都有相同的狀態(tài)頁(yè)面(A頁(yè)面的空布局頁(yè)面和B頁(yè)面的空布局不一定一樣)


20180920233355681.png

20180920233404854.png

所以根據(jù)這個(gè)情況設(shè)置了兩個(gè)方案,設(shè)置默認(rèn)布局,保存在SparseArray<View>中,然后設(shè)置MultiStatusLayoutManager為單例,在其他使用統(tǒng)一默認(rèn)狀態(tài)布局的頁(yè)面都使用這個(gè)單例變量來(lái)展示不同的狀態(tài)布局;并且提供創(chuàng)建普通對(duì)象的方法,以供設(shè)置自定義狀態(tài)布局。

代碼地址:https://github.com/fanturbo/MultiStatusLayoutManager

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,388評(píng)論 25 708
  • 用兩張圖告訴你,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 14,149評(píng)論 2 59
  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,240評(píng)論 3 119
  • 我覺(jué)得如果能把做菜這件事當(dāng)成一種愛(ài)好,其實(shí)是一件挺快樂(lè)的事! 我喜歡做菜,最初做是為了自己喜歡吃,后來(lái)做是為了大家...
    火花客棧閱讀 434評(píng)論 0 1
  • 聽(tīng)說(shuō)悉尼的有錢(qián)人不住市中心,最富的人住東區(qū),次富一點(diǎn)住北區(qū)也就是悉尼海灣以北的地方。雙灣玫瑰灣屬于東區(qū),我們?nèi)ミ^(guò),...
    獨(dú)孤行_蒼茫閱讀 3,066評(píng)論 0 1

友情鏈接更多精彩內(nèi)容