Android 多狀態(tài)加載布局的開發(fā) Tips

作者博客地址: http://gudong.name
本文博客地址: http://gudong.name/2017/04/26/loading_layout_practice.html

本文將結(jié)合自己的項目開發(fā)實踐弹沽,簡單分享一下關(guān)于多狀態(tài) Layout 的開發(fā)實踐 Tips。

什么是多狀態(tài) Layout

對于大多數(shù) App 而言履腋,項目中都有多狀態(tài)加載 View 這種需求欧漱,如下圖所示砰嘁。

demo

對應(yīng)到開發(fā)中污桦,我們通常會開發(fā)一個對應(yīng)的自定義 layout 用于根據(jù)頁面不同的狀態(tài)來顯示不同的提示 view。

在項目中秋泄,我們大多會在開發(fā)初期就把這套 layout 框架寫好阱持,然后其他人的自己的開發(fā)過程中直接使用即可夭拌。如下所示:

<name.gudong.MJMultipleStatusLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/lv_activity_center"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</name.gudong.MJMultipleStatusLayout>

這篇文章不討論如何去實現(xiàn)這樣的自定義 loading layout,Github 上這樣的 layout 太多了衷咽,這里主要思考鸽扁、總結(jié)在實際開發(fā)中開發(fā)這樣的自定義 Layout 時應(yīng)該注意那些地方。

但是為了說明方便镶骗,這里還是采用的方案簡單敘述一下桶现。

為了后文描述方便,這里把這個多狀態(tài)自定義 Layout 先稱為 MultipleStatusLayout鼎姊。

實現(xiàn)方案

在實現(xiàn) MultipleStatusLayout 時骡和,首先選擇繼承一個 ViewGroup 作為自己的父類,然后默認(rèn)把內(nèi)部的第一個子 View 作為 ContentView相寇,其它各種情形下對應(yīng)要顯示的 layout view慰于,根據(jù)不同的加載狀態(tài),在 MultipleStatusLayout 中通過動態(tài) addView 去控制對應(yīng) layout 的加載顯示唤衫,也可以通過 ViewStub 把不同情形的 layout 進行懶加載婆赠,然后對外提供不同的方法,方便外部調(diào)用佳励、控制不同狀態(tài)下的 layout 顯示休里。

嗯蛆挫,簡單說來就是這樣,原理很簡單妙黍,實現(xiàn)起來也沒什么技術(shù)難度悴侵,對于一般的開發(fā)人員只要一開始明白具體的產(chǎn)品邏輯和實現(xiàn)思路,相信花不了多少時間就可以完成這樣的 MultipleStatusLayout拭嫁。具體這種方式的實現(xiàn)可以參看一個開源項目 的實現(xiàn)畜挨。

下面著重列舉一下開發(fā) MultipleStatusLayout 過程中的注意點或者要點。

Tips

考慮到 MultipleStatusLayout 開發(fā)完成后噩凹,會在項目中的很多頁面中應(yīng)用,而且很多時候是作為頁面頂級父容器而存在毡咏,所以開發(fā)過程中一定要注意其性能還有穩(wěn)定性驮宴,否則一旦出現(xiàn)問題,整個項目中應(yīng)用到該 MultipleStatusLayout 的頁面都會隨之出現(xiàn)問題呕缭。

以下就從性能角度、可維護性、穩(wěn)定性等方面考慮出發(fā)闰靴,列舉一些開發(fā) tip 巢掺。

選擇最合理的父容器

首先 FrameLayout、RelativeLayout片仿、LinearLayout 都可以作為 MultipleStatusLayout 的父類纹安,拋開現(xiàn)在的應(yīng)用場景不談,都知道 RelativeLayout 在 layout 時需要 measure 兩次砂豌,所以對于一個未來要在很多頁面中使用的 Layout 厢岂,把 RelativeLayout 作為父類這個方案首先 pass 掉。

但是因為 MultipleStatusLayout 中顯示的 view 大都需要居中顯示阳距,所以使用 RelativeLayout 相對比較容易控制居中位置塔粒,這可能是很多人選擇 RelativeLayout 作為父類的初衷。這里自己可以做一下權(quán)衡筐摘。

關(guān)于 LinearLayout 和 FrameLayout卒茬,如果按照上一節(jié)提到的實現(xiàn)方案,其實都可以采用咖熟,不過考慮到該類 Layout 的應(yīng)用場景圃酵,建議選擇 FrameLayout。

因為MultipleStatusLayout 未來在大多數(shù)情況下是作為頁面父容器存在的馍管,既然是父容器辜昵,內(nèi)容可能會有各種變化咽斧,這時使用 LinearLayout 這種線性布局就會在布局時顯得特別局限堪置,比如一些頁面可能需要在 MultipleStatusLayout 之上顯示一個 FloatActionButton 或者其他的 view躬存,這時使用 FrameLayout 就會好做很多也會靈活很多。

選擇最優(yōu)的加載 View 方式

如何控制這些多狀態(tài)對應(yīng)的 View ? 對于一般的情形舀锨,至少有兩種 View 類型岭洲,一種是加載中的 loading 樣式 view,一種是異常狀態(tài)的 layout view坎匿,當(dāng)然還可能有更多具體的情形盾剩。

不同的樣式對應(yīng)一個不同的布局,為了簡便我們可以一次性的把所有狀態(tài)對應(yīng)的布局都寫在一個 layout 布局里替蔬,然后可以通過控制隱藏告私、顯示來根據(jù)不同的狀態(tài)來展示不同 view,這是最直接的想法承桥。

但是驻粟,只要多思考一步,就會發(fā)現(xiàn)這種方式非常不可取凶异。因為很多時候蜀撑,MultipleStatusLayout 作為一個父容器只關(guān)心自己的 ContentView,異常頁面和加載頁面甚至可能沒有機會出現(xiàn)剩彬,但是現(xiàn)在這樣做就表示酷麦,這個頁面不論有沒有異常或者加載邏輯喉恋,你的布局里都會存在對應(yīng)的 layout 布局代碼沃饶。這樣在界面繪制時就會白白耗掉多余的時間。

而且這個 Layout 后續(xù)會在項目很多頁面用到轻黑,所以這里的布局耗時問題放大后就顯得很嚴(yán)重绍坝。

鑒于此,取而代之的更好的做法應(yīng)該是動態(tài)去 addView苔悦,只有這個頁面第一次調(diào)用 loading 或者 showError 這樣的方法轩褐,我才去把對應(yīng)布局加載進來,當(dāng)然這里使用 ViewStub 也是一樣的效果玖详。

這里也就是說把介,只有調(diào)用了相應(yīng)的方法,才去加載對應(yīng)的 layout.

資源命名

其實這個問題是自己開發(fā)公用 Api 普遍面臨的問題蟋座,由于開發(fā) MultipleStatusLayout 可能會定義一些顏色資源或者背景資源拗踢,這里建議所有資源開頭使用一個固定的開頭,這樣可以防止跟主版本中的資源重名向臀。進而早成一些奇怪的 UI 問題或者編譯問題巢墅。比如按鈕的背景你可以定義為 msl_btn_normal 而不是 btn_normal,文字的顏色你可以定義為 msl_text_white 而不是 text_white。這樣就可以有效避免一些資源沖突君纫。

更多關(guān)于如何開發(fā)一個第三方庫驯遇,可以查看天之界線開發(fā)第三方庫最佳實踐

提供友好的方法調(diào)用方式

既然是提供給大家使用,你就應(yīng)該在方法命名上多花點心思蓄髓,最好見名之意叉庐,這樣大家調(diào)用時也會舒服很多。

另外對外提供 Api 時也應(yīng)該保持克制会喝。不要一下子提供出去太多的方法陡叠,不論有用沒用,一下子都對外提供肢执,這樣會對后續(xù)的維護造成隱形的負擔(dān)枉阵,因為提供的公用方法越多,表示你后續(xù)都要對這些方法進行維護预茄。

最好的原則就是用到什么提供什么兴溜,不要提前設(shè)計。

另外反璃,隨著項目迭代,對外提供方法的參數(shù)可能會變得多起來假夺,比如以前顯示錯誤頁面的方法是

void showErrorView(Stirng error) 

后來要增加自定義的 icon 或者點擊事件響應(yīng)淮蜈,這時你就需要擴展方法參數(shù),往往這種參數(shù)可能會變得很多不可收拾已卷,這時建議使用 Build 構(gòu)建模式設(shè)計梧田,如下示例所示:

showErrorView(StatusViewConfig config) 

調(diào)用時就可以這樣調(diào)用

showErrorView(new StatusViewConfig.StatusViewBuild(getContext())
                .icon(icon)
                .message(message)
                .subMessage(subMessage)
                .layoutMode(mLayoutMode)
                .withActionText(actionText, clickListener)
                .build())

良好的文檔

當(dāng)你開發(fā)完成后,最好趁熱寫一份簡單明了的使用文檔出來侧蘸,這樣大家就可以直接對照文檔使用你寫的庫裁眯,不用去關(guān)心代碼實現(xiàn),直接調(diào)用 Api 就可以完成自己的業(yè)務(wù)需求讳癌,同時也省的自己去面對面跟別人講怎么使用了穿稳。

前段時間在 V 站上看到一個問題,說你們公司使用什么樣的文檔管理工具晌坤?其中有一個回答言簡意賅逢艘,很有意思,四個字 口口相傳骤菠。

其實對于任何一個項目都是它改,有時間寫點文檔,梳理自己思路的同時方便別人商乎,何樂而不為央拖。

其他

這種 Layout 在項目中會隨著項目的更新迭代而不斷的更新,所以一開始你就應(yīng)該知道,后續(xù)還要不斷迭代更新鲜戒,所以代碼設(shè)計實現(xiàn)時應(yīng)該留意擴展性专控。

另外,相關(guān)的開源方案有很多袍啡,建議一開始可以參考一些好的方案踩官,然后結(jié)合自己項目的實際需求,來開發(fā)維護屬于自己項目的一套框架境输。因為多狀態(tài) loading 加載提示框架大都和產(chǎn)品設(shè)計強相關(guān)蔗牡,不具備一般的通用性。

下面列舉一些自己收集到的多狀態(tài)加載開源方案嗅剖,方便對比辩越。

開源方案

StatefulLayout

progress-activity

StateLayout

MultipleStatusView

KingJA/LoadSir

總結(jié)

同樣功能的 Layout 可能在不同的業(yè)務(wù)場景下實現(xiàn)方式也會有很大的區(qū)別,所以不論哪種實現(xiàn)方式信粮,無所謂好壞黔攒,只要適合就好。但是開發(fā)此類 Layout 要遵循的基本準(zhǔn)則强缘、以及要注意的點應(yīng)該大都相同督惰,希望此文可以給你一些啟示幫助。

本文原創(chuàng)發(fā)布于公眾號 大俠咕咚旅掂,歡迎掃碼關(guān)注更多原創(chuàng)文章赏胚。


大俠咕咚
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市商虐,隨后出現(xiàn)的幾起案子觉阅,更是在濱河造成了極大的恐慌,老刑警劉巖秘车,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件典勇,死亡現(xiàn)場離奇詭異,居然都是意外死亡叮趴,警方通過查閱死者的電腦和手機割笙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眯亦,“玉大人咳蔚,你說我怎么就攤上這事∩ν眨” “怎么了谈火?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長舌涨。 經(jīng)常有香客問我糯耍,道長扔字,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任温技,我火速辦了婚禮革为,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘舵鳞。我一直安慰自己震檩,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布蜓堕。 她就那樣靜靜地躺著抛虏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪套才。 梳的紋絲不亂的頭發(fā)上迂猴,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天,我揣著相機與錄音背伴,去河邊找鬼沸毁。 笑死,一個胖子當(dāng)著我的面吹牛傻寂,可吹牛的內(nèi)容都是我干的息尺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼疾掰,長吁一口氣:“原來是場噩夢啊……” “哼搂誉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起个绍,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤勒葱,失蹤者是張志新(化名)和其女友劉穎浪汪,沒想到半個月后巴柿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡死遭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年广恢,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片呀潭。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡钉迷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钠署,到底是詐尸還是另有隱情糠聪,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布谐鼎,位于F島的核電站舰蟆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜身害,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一味悄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧塌鸯,春花似錦侍瑟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至淮悼,卻和暖如春咐低,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背袜腥。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工见擦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人羹令。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓鲤屡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親福侈。 傳聞我的和親對象是個殘疾皇子酒来,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,507評論 2 359

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,283評論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件肪凛、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,119評論 4 61
  • 我滿腔熱血 你陌陌桑桑 我天天地地 你昏昏暗暗 藍天青草牛馬 女女緑緑紅紅 誰誰展開雙眼 誰誰日日年年
    小小仲馬閱讀 202評論 2 1
  • 哈哈哈哈哈哈哈哈哈畫了一只小綿羊 綿羊畫了好多遍orz 過幾天去買勾線筆堰汉。。
    辣眼睛的小草莓閱讀 141評論 0 0
  • 昨天偶然間發(fā)現(xiàn)了簡書伟墙,驚喜于在我們?nèi)粘5腁PP之外翘鸭,真的有人在營造著文字里的世界,在這里戳葵,只要你文章寫的好就乓,就能找...
    竹木成雙閱讀 250評論 0 0