Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BindingAdapter分页加载需求下组的合并的方法 #425

Open
XXQAQ opened this issue Mar 5, 2024 · 0 comments
Open

BindingAdapter分页加载需求下组的合并的方法 #425

XXQAQ opened this issue Mar 5, 2024 · 0 comments

Comments

@XXQAQ
Copy link

XXQAQ commented Mar 5, 2024

描述

现有的BindingAdapter的addModels内部处理好了分组的嵌套结构,但目前的方式是将新增的所有元素视为一个完整的嵌套组进行处理。
在绝大多数异步分页加载中,组的数量不恒定,会随着分页加载数据的增多而增多。所以每次请求到的数据可能属于在上一页数据中的最后一个分组(也就是一个组的数据会跨多页)。
并且考虑到组与组是可以递归嵌套的,需要写非常复杂的算法才能将多组的数据进行合并。所以我提供了一种算法,可以递归合并分组数据
joinMergeModels 方法的含义是: 每次调用该方法时,如果当前List中的第一个组与Models中的最后一个组为同一组,那么将当前List的第一组合并至Models的最后一组中。该算法支持组的递归嵌套关系,用中文来描述意思就是:支持当前List的第一个组的第一个组的一个组的...的数据与Models中的最后一个组的最后一个组的最后一个组...的数据进行合并

参考实现

fun joinMergeModels(list: List<Any?>?){
    if (list.isNullOrEmpty()){
        return
    }
    val insertIndex = modelCount
    val byAffectedList = ArrayList<Any?>()
    val flatList = mergeList(expandListToCollapseList(mutable),list.toMutableList(),byAffectedList)
    //先新增
    mutable.addAll(flatList)
    notifyItemRangeInserted(insertIndex, flatList.size)
    //将受到影响的父节点挨个更新
    for (affected in byAffectedList.reversed()){
        notifyItemChanged(mutable.indexOf(affected))
    }
    //
    rv?.post {
        rv?.invalidateItemDecorations()
    }
}

private fun mergeList(srcList: MutableList<Any?>, insertList: MutableList<Any?>, byAffectedList: MutableList<Any?>): List<Any?>{
    val flatList = ArrayList<Any?>()
    val firstInInsert = insertList.firstOrNull()
    val lastInSrc = srcList.lastOrNull()
    if (lastInSrc is ItemExpand && firstInInsert is ItemExpand && lastInSrc is ItemStableId && firstInInsert is ItemStableId && lastInSrc.getItemId() == firstInInsert.getItemId()){
        byAffectedList.add(lastInSrc)
        val lastFlatGroupList = mergeList(lastInSrc.getItemSublist(),firstInInsert.getItemSublist(),byAffectedList)
        if (lastInSrc.itemExpand){
            flatList.addAll(lastFlatGroupList)
        }
        flatList.addAll(insertAndFlat(srcList,insertList.subList(1,insertList.size)))
    } else{
        flatList.addAll(insertAndFlat(srcList,insertList))
    }
    return flatList
}

private fun insertAndFlat(srcList: MutableList<Any?>, insertList: MutableList<Any?>): List<Any?>{
    srcList.addAll(insertList)
    return flat(insertList)
}

private fun expandListToCollapseList(list: List<Any?>): MutableList<Any?>{
    val result = ArrayList<Any?>()
    for (any in list){
        val last = result.lastOrNull()
        if (last is ItemExpand && isNestedChild(last,any)){
            // 不用再递归了
        } else{
            result.add(any)
        }
    }
    return result
}

private fun isNestedChild(itemExpand: ItemExpand,any: Any?): Boolean{
    return itemExpand.getItemSublist().contains(any) || itemExpand.getItemSublist().any {
        it is ItemExpand && isNestedChild(it,any)
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant