Paging+Network的數(shù)據(jù)增刪改刷新處理

本文給出了我對(duì)與當(dāng)前Paging+Network數(shù)據(jù)修改的處理方法

網(wǎng)絡(luò)上的處理方案

1、簡單粗暴,直接刷新數(shù)據(jù)使用


adapter?.currentlist?.dataSource?.invalidate()

這樣會(huì)重新調(diào)用init初始化數(shù)據(jù),刷新頁面。

缺點(diǎn):刷新后會(huì)回到列表頂部,不能刷新到分頁處。需要重新load數(shù)據(jù)

明顯該方案在分頁數(shù)據(jù)的情況下,體驗(yàn)很糟糕基本上是不可取的

2、借助db或者memory緩存來實(shí)現(xiàn),具體可以參考官方的demo,本質(zhì)上是多了一級(jí)存儲(chǔ),不過db或memory上數(shù)據(jù)的變化會(huì)實(shí)時(shí)刷新到頁面

缺點(diǎn):實(shí)現(xiàn)相對(duì)比較復(fù)雜,而且多了一級(jí)緩存,需要考慮緩存的更新同步策略。

總結(jié):在方案一不可取,方案二又顯得冗余的情況下,難道真的要妥協(xié)了嗎?有沒有既能實(shí)現(xiàn)效果,又不那么復(fù)雜的方法呢?

我的方案

既然要對(duì)數(shù)據(jù)做增刪改,在和服務(wù)端交互完成后,我們自己是知道修改后數(shù)據(jù)是什么樣的,自然能通過現(xiàn)有數(shù)據(jù)構(gòu)造出新的數(shù)據(jù)來。這里我們不事先緩存所有數(shù)據(jù),只是增刪改之后自己生成增刪改之后的數(shù)據(jù)。然后就是怎么刷新到頁面上了,這個(gè)問題很簡單,我們借助adapter?.currentlist?.dataSource?.invalidate(),調(diào)用之后會(huì)重新調(diào)用DataSource的loadInitial方法去重新初始化數(shù)據(jù),這里我們就不再去網(wǎng)絡(luò)請(qǐng)求了,直接使用我們構(gòu)造的數(shù)據(jù),這樣整個(gè)流程就連接起來了,這里需要注意的有兩點(diǎn),一個(gè)是我們自己構(gòu)造的數(shù)據(jù)只能在我們?cè)鰟h改之后使用,使用完了就沒有用了可以清除了。另一個(gè)就是我們自己構(gòu)造的數(shù)據(jù)如何給DataSource,這里我們考慮到由于沒有通過網(wǎng)絡(luò)請(qǐng)求,所有數(shù)據(jù)構(gòu)造以及到loadInitial過程都是同步,且DataSource在invalidate后會(huì)重新創(chuàng)建,所以構(gòu)造的數(shù)據(jù)用一個(gè)靜態(tài)變量存儲(chǔ),雖然數(shù)據(jù)可能會(huì)很大,但是這個(gè)數(shù)據(jù)存在時(shí)間很短暫,用完就清除了,所以代價(jià)算是比較小吧。

下面是簡單的代碼:

首先添加用于存儲(chǔ)臨時(shí)數(shù)據(jù)的變量,然后添加一個(gè)外部調(diào)用的post更新后的數(shù)據(jù)的方法。


val DataSource<*, *>.tempList: MutableList<Any>

    get() = tempDataSourceList

//存儲(chǔ)構(gòu)建的用于本地刷新的臨時(shí)數(shù)據(jù)

val tempDataSourceList:MutableList<Any> = ArrayList()

//給出構(gòu)造的數(shù)據(jù),并發(fā)出刷新動(dòng)作

fun DataSource<*, *>.postChangedList(list: List<Any>){

    tempList.clear()

    tempList.addAll(list)

    invalidate()

}

fun DataSource<*, *>.isLocalUpdate():Boolean{

    return tempList.isNotEmpty()

}

然后再對(duì)應(yīng)DataSource的loadInitial方法中做如下判斷:


//如果是本地刷新,直接傳入數(shù)據(jù)返回

if (isLocalUpdate()) {

    initSuccess(tempList)

//臨時(shí)數(shù)據(jù)使用完成及時(shí)清除

    tempList.clear()

    return

}

//正常邏輯,請(qǐng)求然后刷新數(shù)據(jù)

//...

接下來是增刪改之后調(diào)用:


val currentList = adapter.currentList?.snapshot()

//        ...對(duì)數(shù)據(jù)做具體增刪改操作,以刪除最后一條數(shù)據(jù)為例

currentList?.removeAt(currentList.lastIndex)

adapter.currentList?.dataSource?.postChangedList(currentList?.toList()?: emptyList())

沒錯(cuò)就是這么簡單,全部加起來也不過十幾行代碼,第一部分是通用的代碼,其余的是在自己業(yè)務(wù)代碼的地方添加。

如果有不正確的地方或者還有可優(yōu)化的地方歡迎指出。

?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 懶得處理樣式了, 將就著看吧. 官網(wǎng)地址: https://developer.android.com/topic...
    Reddington_604e閱讀 1,910評(píng)論 0 1
  • 一、簡歷準(zhǔn)備 1、個(gè)人技能 (1)自定義控件、UI設(shè)計(jì)、常用動(dòng)畫特效 自定義控件 ①為什么要自定義控件? Andr...
    lucas777閱讀 5,385評(píng)論 2 54
  • 1. 簡介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲(chǔ)過程以及高級(jí)映射的優(yōu)秀的...
    笨鳥慢飛閱讀 6,232評(píng)論 0 4
  • 基礎(chǔ) 1. 為什么說Objective-C是一門動(dòng)態(tài)的語言? 2. 講一下MVC和MVVM,MVP? 3. 為...
    波妞和醬豆子閱讀 3,526評(píng)論 0 46
  • 1.JVM 堆內(nèi)存和非堆內(nèi)存 堆和非堆內(nèi)存按照官方的說法:“Java 虛擬機(jī)具有一個(gè)堆(Heap),堆是運(yùn)行時(shí)數(shù)據(jù)...
    yanzhu728閱讀 1,002評(píng)論 0 0

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