色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術文章
文章詳情頁

Android 基于MediatorLiveData實現紅點的統一管理

瀏覽:11日期:2022-09-19 17:38:53
背景

小紅點在各個App內隨處可見,并且隨著需求的不斷迭代,需要展示小紅點的需求越來越多。

不同需求之間,紅點顯示可能有沖突。 不同頁面之間,紅點顯示會有關聯。 同一個紅點,可能顯示成數字樣式,紅點樣式,文案樣式。

這個時候,如果沒有對紅點的展示邏輯做一個統一的抽象和管理的話,就會感覺很復雜,后續也不太好維護。

本文會基于MediatorLiveData,實現對紅點的統一管理。

需求分析

這里舉個例子,常見的紅點場景,類似qq首頁左上角紅點的顯示。

4個頁面,由首頁進入到隱私保護指引頁面,都有相應的紅點View顯示,去引導用戶進入到最里面的'隱私保護指引'頁面。 當用戶點擊紅點,進入到'隱私保護指引'頁面后,隱私保護指引對應的紅點就會消失,同時會觸發上級頁面的紅點刷新。

Android 基于MediatorLiveData實現紅點的統一管理

Android 基于MediatorLiveData實現紅點的統一管理

思路分析樹形模型

一個App的頁面本身就是分級的,對于頁面的訪問路徑本質上就是個樹型結構。 整體的實現思路是用樹形模型去管理不同頁面的紅點。

每個小紅點就是一個樹的節點,父節點的小紅點是否顯示,取決于它的子節點的并集結果。 同一個頁面中的不同紅點。在樹中是同一個層級,屬于兄弟關系,互相獨立。 子節點的狀態變化,會遞歸地去觸發父節點的狀態變化。

Android 基于MediatorLiveData實現紅點的統一管理

具體代碼實現

那對應的代碼應該如何實現呢,難道真的要手動自己實現一棵樹?也不是不行,就是感覺有點小麻煩的樣子。 下面進入正題。

MediatorLiveData

官方提供了MediatorLiveData。

通過addSource方法,可以監聽另一個LiveData的數據變化 本身就是一個LiveData,可以被其他Observer觀察

這兩個特點,剛好滿足我們的需求實現。比如MediatorLiveData A觀察 MediatorLiveData B,MediatorLiveData B觀察 MediatorLiveData C 和MediatorLiveData D。并且被觀察的LiveData發生變化,作為觀察的LiveData都能收到通知。

通過管理多個LiveData之間的關系,這樣就可以間接實現了一棵樹的模型。

Android 基于MediatorLiveData實現紅點的統一管理

public class MediatorLiveData<T> extends MutableLiveData<T> { private SafeIterableMap<LiveData<?>, Source<?>> mSources = new SafeIterableMap<>(); public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) { //使用Source包一下 Source<S> e = new Source<>(source, onChanged); Source<?> existing = mSources.putIfAbsent(source, e); if (hasActiveObservers()) { e.plug(); } } private static class Source<V> implements Observer<V> { final LiveData<V> mLiveData; final Observer<? super V> mObserver; int mVersion = START_VERSION; Source(LiveData<V> liveData, final Observer<? super V> observer) { mLiveData = liveData; mObserver = observer; } void plug() { mLiveData.observeForever(this); } void unplug() { mLiveData.removeObserver(this); } @Override public void onChanged(@Nullable V v) { if (mVersion != mLiveData.getVersion()) {mVersion = mLiveData.getVersion();mObserver.onChanged(v); } } }}RedPointManager 這里的實現,封裝成一個單例RedPointManager,暴露相應的紅點數據給外部。 LiveData數據驅動:RedPointManager內包含了多個LiveData,不同頁面的紅點View可以通過觀察對應的LiveData,來驅動自身的視圖變化。 父節點使用MediatorLiveData,觀察相應的子節點LiveData。 葉子節點定義成普通的LiveData就行了,因為不需要觀察其他對象了。

Android 基于MediatorLiveData實現紅點的統一管理

/** * 基于MediatorLiveData,實現樹形紅點管理 */class RedPointManager : IRedPointManager { companion object { val TAG = 'RedPointManager' @JvmStatic val instance: IRedPointManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { RedPointManager() } } override val liveDataA = MediatorLiveData<Boolean>() override val liveDataB1 = MediatorLiveData<Boolean>() override val liveDataB2 = MutableLiveData<Boolean>() override val liveDataC1 = MutableLiveData<Boolean>() override val liveDataC2 = MutableLiveData<Boolean>() init { Log.d(TAG, 'RedPointManager init') /** * 構建樹型關系。按路徑層級,進行觀察。一般外部只需要改動最低層的紅點對應的LiveData,頂部的LiveData就會自動改變 */ liveDataA.addSource(liveDataB1, Observer { liveDataA.postValue(liveDataB1.isTrue() || liveDataB2.isTrue()) }) liveDataA.addSource(liveDataB2, Observer { liveDataA.postValue(liveDataB1.isTrue() || liveDataB2.isTrue()) }) liveDataB1.addSource(liveDataC1, Observer { liveDataB1.postValue(liveDataC1.isTrue() || liveDataC2.isTrue()) }) liveDataB1.addSource(liveDataC2, Observer { liveDataB1.postValue(liveDataC1.isTrue() || liveDataC2.isTrue()) }) } override fun testChangeDataC1(show: Boolean) { liveDataC1.postValue(show) Log.d(TAG, 'testChangeDataC1: $show') }}/** * 定義接口 * 提供只讀的屬性,提供修改liveData的方法 */interface IRedPointManager { val liveDataA: LiveData<Boolean> val liveDataB1: LiveData<Boolean> val liveDataB2: LiveData<Boolean> val liveDataC1: LiveData<Boolean> val liveDataC2: LiveData<Boolean> fun testChangeDataC1(show: Boolean)}驗證刷新邏輯

一般情況下,只需要改動葉子節點的紅點對應的LiveData,父節點的LiveData就會自動改變。 基于上述代碼,調用testChangeDataC1方法后,監聽LiveData并輸出日志。

private fun testRedPointManager() { RedPointManager.instance.liveDataA.observe(this, Observer { Log.d(TAG, 'liveDataA: $it') }) RedPointManager.instance.liveDataB1.observe(this, Observer { Log.d(TAG, 'liveDataB1: $it') }) RedPointManager.instance.liveDataB2.observe(this, Observer { Log.d(TAG, 'liveDataB2: $it') }) RedPointManager.instance.liveDataC1.observe(this, Observer { Log.d(TAG, 'liveDataC1: $it') }) RedPointManager.instance.liveDataC2.observe(this, Observer { Log.d(TAG, 'liveDataC2: $it') }) RedPointManager.instance.testChangeDataC1(true) } //從輸出日志可以發現,底層的liveDataC1發生改變,觸發頂層的liveDataB1發生改變。liveDataB1的變化,也觸發了liveDataA發生改變。RedPointManager inittestChangeDataC1: trueliveDataC1: truelveDataB1: trueliveDataA: true總結

到這里就結束了,App端內實現紅點的統一管理,如果有類似的場景,可以用這種思路去實現。 上面的例子比較簡單,更復雜的場景,應該也是可以基于上面的方案進行改造一下的。

以上就是Android 基于MediatorLiveData實現紅點的統一管理的詳細內容,更多關于MediatorLiveData實現紅點的統一管理的資料請關注好吧啦網其它相關文章!

標簽: Android
相關文章:
主站蜘蛛池模板: 日本亚欧乱色视频在线观看 | 精品99在线观看 | 99久久精品国产自免费 | 欧美日产国产亚洲综合图区一 | 草草免费观看视频在线 | 俄罗斯18videosex性欧美成人 | 亚洲视频精品在线 | 国产人做人爱免费视频 | 久久五月女厕所一区二区 | 在线久久 | 欧美一线视频 | 亚洲一区三区 | 久久99久久精品久久久久久 | 毛片b| 成人欧美一区二区三区黑人免费 | 91原创视频在线观看 | 日本久久精品视频 | 天天摸天天爽视频69视频 | 亚洲黄色小视频 | 高h原耽肉汁动漫视频 | 国产精品久久免费观看 | 欧美一区二区在线观看视频 | 国产资源精品一区二区免费 | 亚洲男人天堂久久 | 久久91精品国产91久久 | 日本无卡码一区二区三区 | 欧美成人高清 | 亚洲精品久久玖玖玖玖 | 在线免费观看日本视频 | 一品道一本香蕉视频 | 亚洲国产成人久久一区久久 | 成人做爰视频www片 成人做爰视频www视频 | 可以免费观看欧美一级毛片 | 99在线国产视频 | 免费久久精品 | 男女同床爽爽视频免费 | 国产在线一区二区 | 国产精品久久一区一区 | 久久国产精品视频一区 | 成人免费视频日本 | 欧美天堂 |