Skip to content

Commit 2994148

Browse files
author
Alex
committed
add AsyncDiffModelAdapter.kt
1 parent c985bc9 commit 2994148

4 files changed

Lines changed: 119 additions & 12 deletions

File tree

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ afterEvaluate {
5252
release(MavenPublication) {
5353
from components.release
5454
groupId = 'com.alexdeww.fastadapterdelegate'
55-
version = '2.0.3'
55+
version = '2.0.4'
5656
}
5757
}
5858
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.alexdeww.fastadapterdelegate.adapters
2+
3+
import android.annotation.SuppressLint
4+
import android.os.Handler
5+
import android.os.Looper
6+
import androidx.recyclerview.widget.AsyncDifferConfig
7+
import androidx.recyclerview.widget.DiffUtil
8+
import androidx.recyclerview.widget.RecyclerView
9+
import com.alexdeww.fastadapterdelegate.diffutil.FastAdapterDiffCallback
10+
import com.alexdeww.fastadapterdelegate.diffutil.FastAdapterListUpdateCallback
11+
import com.alexdeww.fastadapterdelegate.wrappers.ModelItemDiffCallbackWrapper
12+
import com.mikepenz.fastadapter.IModelItem
13+
import com.mikepenz.fastadapter.adapters.ModelAdapter
14+
import com.mikepenz.fastadapter.diff.FastAdapterDiffUtil
15+
import java.util.concurrent.Executor
16+
17+
@SuppressLint("RestrictedApi")
18+
open class AsyncDiffModelAdapter<Model : Any, Item : IModelItem<out Model, out RecyclerView.ViewHolder>>(
19+
private val asyncDifferConfig: AsyncDifferConfig<Model>,
20+
interceptor: (element: Model) -> Item?
21+
) : ModelAdapter<Model, Item>(interceptor) {
22+
23+
companion object {
24+
private val DEF_MAIN_THREAD_EXECUTOR by lazy { DefaultMainThreadExecutor() }
25+
}
26+
27+
private var globalRunId: Int = 0
28+
private val mainThreadExecutor by lazy {
29+
asyncDifferConfig.mainThreadExecutor ?: DEF_MAIN_THREAD_EXECUTOR
30+
}
31+
private val itemsDiffCallback = ModelItemDiffCallbackWrapper(asyncDifferConfig.diffCallback)
32+
33+
fun submitList(newList: List<Model>) {
34+
val runId = ++globalRunId
35+
val newItemsList = intercept(newList)
36+
val oldItemsList = FastAdapterDiffUtil.prepare(this, newItemsList)
37+
val diffCb = FastAdapterDiffCallback(oldItemsList, newItemsList, itemsDiffCallback)
38+
asyncDifferConfig.backgroundThreadExecutor.execute {
39+
val diffResult = DiffUtil.calculateDiff(diffCb, true)
40+
mainThreadExecutor.execute {
41+
if (globalRunId == runId) applyListChanges(newItemsList, diffResult)
42+
}
43+
}
44+
}
45+
46+
private fun applyListChanges(newItemsList: List<Item>, diffResult: DiffUtil.DiffResult) {
47+
FastAdapterDiffUtil.postCalculate(this, newItemsList)
48+
diffResult.dispatchUpdatesTo(FastAdapterListUpdateCallback(this))
49+
}
50+
51+
private class DefaultMainThreadExecutor : Executor {
52+
private val handler = Handler(Looper.getMainLooper())
53+
54+
override fun execute(command: Runnable) {
55+
handler.post(command)
56+
}
57+
58+
}
59+
60+
}

app/src/main/java/com/alexdeww/fastadapterdelegate/adapters/DiffModelAdapter.kt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
11
package com.alexdeww.fastadapterdelegate.adapters
22

33
import androidx.recyclerview.widget.DiffUtil
4-
import com.mikepenz.fastadapter.GenericItem
4+
import androidx.recyclerview.widget.RecyclerView
5+
import com.alexdeww.fastadapterdelegate.diffutil.FastAdapterDiffCallback
6+
import com.alexdeww.fastadapterdelegate.diffutil.FastAdapterListUpdateCallback
7+
import com.alexdeww.fastadapterdelegate.wrappers.ModelItemDiffCallbackWrapper
58
import com.mikepenz.fastadapter.IAdapterNotifier
9+
import com.mikepenz.fastadapter.IModelItem
610
import com.mikepenz.fastadapter.adapters.ModelAdapter
711
import com.mikepenz.fastadapter.diff.FastAdapterDiffUtil
8-
import com.alexdeww.fastadapterdelegate.diffutil.FastAdapterDiffCallback
9-
import com.alexdeww.fastadapterdelegate.diffutil.FastAdapterListUpdateCallback
1012

11-
open class DiffModelAdapter<Model, Item : GenericItem>(
12-
protected val diffCallback: DiffUtil.ItemCallback<Item>,
13+
open class DiffModelAdapter<Model : Any, Item : IModelItem<out Model, out RecyclerView.ViewHolder>>(
14+
diffCallback: DiffUtil.ItemCallback<Model>,
1315
interceptor: (element: Model) -> Item?
1416
) : ModelAdapter<Model, Item>(interceptor) {
1517

18+
protected val itemsDiffCallback = ModelItemDiffCallbackWrapper<Model, Item>(diffCallback)
19+
1620
override fun setInternal(
1721
items: List<Item>,
1822
resetFilter: Boolean,
1923
adapterNotifier: IAdapterNotifier?
2024
): ModelAdapter<Model, Item> {
2125
val oldItems = FastAdapterDiffUtil.prepare(this, items)
22-
val diffCallback = FastAdapterDiffCallback(oldItems, items, diffCallback)
26+
val diffCallback = FastAdapterDiffCallback(oldItems, items, itemsDiffCallback)
2327
val diffResult = DiffUtil.calculateDiff(diffCallback, true)
2428
FastAdapterDiffUtil.postCalculate(this, items)
2529
diffResult.dispatchUpdatesTo(FastAdapterListUpdateCallback(this))

app/src/main/java/com/alexdeww/fastadapterdelegate/delegates/adapters/DelegationDiffModelAdapter.kt

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package com.alexdeww.fastadapterdelegate.delegates.adapters
22

3+
import androidx.recyclerview.widget.AsyncDifferConfig
34
import androidx.recyclerview.widget.DiffUtil
5+
import com.alexdeww.fastadapterdelegate.adapters.AsyncDiffModelAdapter
46
import com.alexdeww.fastadapterdelegate.adapters.DiffModelAdapter
57
import com.alexdeww.fastadapterdelegate.delegates.ModelItemDelegate
68
import com.alexdeww.fastadapterdelegate.delegates.item.common.GenericDelegationModelItem
7-
import com.alexdeww.fastadapterdelegate.wrappers.ModelItemDiffCallbackWrapper
89

910
/**
1011
* Адаптер.
@@ -14,11 +15,13 @@ import com.alexdeww.fastadapterdelegate.wrappers.ModelItemDiffCallbackWrapper
1415
* @param diffCallback diffUtilItemCallback()
1516
*/
1617
open class DelegationDiffModelAdapter<BaseModel : Any>(
17-
protected val delegates: List<ModelItemDelegate<BaseModel>>,
18+
delegates: List<ModelItemDelegate<BaseModel>>,
1819
diffCallback: DiffUtil.ItemCallback<BaseModel>
1920
) : DiffModelAdapter<BaseModel, GenericDelegationModelItem<BaseModel>>(
20-
ModelItemDiffCallbackWrapper(diffCallback),
21-
{ model -> delegates.find { it.isForViewType(model) }?.intercept(model, delegates) }
21+
diffCallback = diffCallback,
22+
interceptor = { model ->
23+
delegates.find { it.isForViewType(model) }?.intercept(model, delegates)
24+
}
2225
)
2326

2427
/**
@@ -31,4 +34,44 @@ open class DelegationDiffModelAdapter<BaseModel : Any>(
3134
fun <BaseModel : Any> delegationDiffModelAdapter(
3235
diffCallback: DiffUtil.ItemCallback<BaseModel>,
3336
vararg delegates: ModelItemDelegate<BaseModel>
34-
) = DelegationDiffModelAdapter(delegates.asList(), diffCallback)
37+
): DelegationDiffModelAdapter<BaseModel> = DelegationDiffModelAdapter(
38+
delegates = delegates.asList(),
39+
diffCallback = diffCallback
40+
)
41+
42+
43+
open class DelegationAsyncDiffModelAdapter<BaseModel : Any>(
44+
delegates: List<ModelItemDelegate<BaseModel>>,
45+
asyncDifferConfig: AsyncDifferConfig<BaseModel>,
46+
) : AsyncDiffModelAdapter<BaseModel, GenericDelegationModelItem<BaseModel>>(
47+
asyncDifferConfig = asyncDifferConfig,
48+
interceptor = { model ->
49+
delegates.find { it.isForViewType(model) }?.intercept(model, delegates)
50+
}
51+
) {
52+
53+
constructor(
54+
delegates: List<ModelItemDelegate<BaseModel>>,
55+
diffCallback: DiffUtil.ItemCallback<BaseModel>
56+
) : this(
57+
delegates = delegates,
58+
asyncDifferConfig = AsyncDifferConfig.Builder(diffCallback).build()
59+
)
60+
61+
}
62+
63+
fun <BaseModel : Any> delegationAsyncDiffModelAdapter(
64+
asyncDifferConfig: AsyncDifferConfig<BaseModel>,
65+
vararg delegates: ModelItemDelegate<BaseModel>
66+
): DelegationAsyncDiffModelAdapter<BaseModel> = DelegationAsyncDiffModelAdapter(
67+
delegates = delegates.asList(),
68+
asyncDifferConfig = asyncDifferConfig
69+
)
70+
71+
fun <BaseModel : Any> delegationAsyncDiffModelAdapter(
72+
diffCallback: DiffUtil.ItemCallback<BaseModel>,
73+
vararg delegates: ModelItemDelegate<BaseModel>
74+
): DelegationAsyncDiffModelAdapter<BaseModel> = DelegationAsyncDiffModelAdapter(
75+
delegates = delegates.asList(),
76+
diffCallback = diffCallback
77+
)

0 commit comments

Comments
 (0)