1+ package org.cgsdream.demo
2+
3+ import android.support.v7.util.DiffUtil
4+ import android.util.SparseArray
5+
6+ /* *
7+ * Created by cgspine on 2018/1/26.
8+ */
9+
10+ class DiffCallback <H : Cloneable <H >, T : Cloneable <T >>(private val oldList : List <Section <H , T >>, private val newList : List <Section <H , T >>) : DiffUtil.Callback() {
11+
12+ private val mOldSectionIndex: SparseArray <Int > = SparseArray ()
13+ private val mOldItemIndex: SparseArray <Int > = SparseArray ()
14+
15+ private val mNewSectionIndex: SparseArray <Int > = SparseArray ()
16+ private val mNewItemIndex: SparseArray <Int > = SparseArray ()
17+
18+ init {
19+ generateIndex(oldList, mOldSectionIndex, mOldItemIndex)
20+ generateIndex(newList, mNewSectionIndex, mNewItemIndex)
21+
22+ }
23+
24+ override fun areItemsTheSame (oldItemPosition : Int , newItemPosition : Int ): Boolean {
25+
26+ val oldSectionIndex = mOldSectionIndex[oldItemPosition]
27+ val oldItemIndex = mOldItemIndex[oldItemPosition]
28+ val oldModel = oldList[oldSectionIndex]
29+
30+ val newSectionIndex = mNewSectionIndex[newItemPosition]
31+ val newItemIndex = mNewItemIndex[newItemPosition]
32+ val newModel = newList[newSectionIndex]
33+
34+ if (oldModel.header != newModel.header) {
35+ return false
36+ }
37+
38+ if (oldItemIndex < 0 && oldItemIndex == newItemIndex) {
39+ return true
40+ }
41+
42+ if (oldItemIndex < 0 || newItemIndex < 0 ) {
43+ return false
44+ }
45+ return oldModel.list[oldItemIndex] == newModel.list[newItemIndex]
46+ }
47+
48+ override fun getOldListSize () = mOldSectionIndex.size()
49+
50+ override fun getNewListSize () = mNewSectionIndex.size()
51+
52+ override fun areContentsTheSame (oldItemPosition : Int , newItemPosition : Int ): Boolean {
53+
54+ val oldSectionIndex = mOldSectionIndex[oldItemPosition]
55+ val oldItemIndex = mOldItemIndex[oldItemPosition]
56+ val oldModel = oldList[oldSectionIndex]
57+
58+ val newSectionIndex = mNewSectionIndex[newItemPosition]
59+ val newModel = newList[newSectionIndex]
60+
61+ if (oldItemIndex == ITEM_INDEX_SECTION_HEADER ) {
62+ return oldModel.isFold == newModel.isFold
63+ }
64+
65+ if (oldItemIndex == ITEM_INDEX_LOAD_BEFORE || oldItemIndex == ITEM_INDEX_LOAD_AFTER ) {
66+ // load more 强制返回 false,这样可以通过 FolderAdapter.onViewAttachedToWindow 触发 load more
67+ return false
68+ }
69+
70+ return true
71+ }
72+
73+ companion object {
74+ val ITEM_INDEX_SECTION_HEADER = - 1
75+ val ITEM_INDEX_LOAD_BEFORE = - 2
76+ val ITEM_INDEX_LOAD_AFTER = - 3
77+
78+ fun <H : Cloneable <H >, T : Cloneable <T >> generateIndex (list : List <Section <H , T >>,
79+ sectionIndex : SparseArray <Int >,
80+ itemIndex : SparseArray <Int >){
81+ sectionIndex.clear()
82+ itemIndex.clear()
83+ var i = 0
84+ list.forEachIndexed { index, it ->
85+ if (! it.isLocked) {
86+ sectionIndex.append(i, index)
87+ itemIndex.append(i, ITEM_INDEX_SECTION_HEADER )
88+ i++
89+ if (! it.isFold && it.count() > 0 ) {
90+ if (it.hasBefore) {
91+ sectionIndex.append(i, index)
92+ itemIndex.append(i, ITEM_INDEX_LOAD_BEFORE )
93+ i++
94+ }
95+
96+ for (j in 0 until it.count()) {
97+ sectionIndex.append(i, index)
98+ itemIndex.append(i, j)
99+ i++
100+ }
101+
102+ if (it.hasAfter) {
103+ sectionIndex.append(i, index)
104+ itemIndex.append(i, ITEM_INDEX_LOAD_AFTER )
105+ i++
106+ }
107+ }
108+ }
109+ }
110+ }
111+ }
112+ }
0 commit comments