Skip to content

Commit 0551a5c

Browse files
yigitelihart
authored andcommitted
Paged list controller (#533)
* EpoxyController that works with PagedList This CL introduces a new class in epoxy-paging called CachingPagingEpoxyController. This controller works with a PagedList and caches models for each item. It still allows modifying the final model list via an addModels API. Fixes: 524 Test: PagedListModelCacheTest * More docs and style fixes * more docs & cleanup based on comments * Rename caching paging to PagedListEpoxyController * update sample not to add items randomly, it is confusing
1 parent e50f1a5 commit 0551a5c

File tree

13 files changed

+797
-89
lines changed

13 files changed

+797
-89
lines changed

blessedDeps.gradle

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ rootProject.ext.MIN_SDK_VERSION_LITHO = 15
1717

1818
rootProject.ext.ANDROID_SUPPORT_LIBS_VERSION = "27.1.0"
1919
rootProject.ext.ANDROID_DATA_BINDING = "1.3.1"
20-
rootProject.ext.ANDROID_PAGING = "1.0.0-beta1"
20+
rootProject.ext.ANDROID_PAGING = "1.0.1"
21+
rootProject.ext.ANDROID_ARCH_TESTING = "1.1.1"
22+
rootProject.ext.ANDROID_TEST_RUNNER = "1.0.2"
2123
rootProject.ext.BUTTERKNIFE_VERSION = "8.8.1"
2224
rootProject.ext.SQUARE_JAVAPOET_VERSION = "1.11.1"
2325
rootProject.ext.SQUARE_KOTLINPOET_VERSION = "0.7.0"
@@ -44,6 +46,8 @@ rootProject.ext.deps = [
4446
androidDesignLibrary : "com.android.support:design:$ANDROID_SUPPORT_LIBS_VERSION",
4547
androidRecyclerView : "com.android.support:recyclerview-v7:$ANDROID_SUPPORT_LIBS_VERSION",
4648
androidPagingComponent: "android.arch.paging:runtime:$ANDROID_PAGING",
49+
androidArchCoreTesting: "android.arch.core:core-testing:$ANDROID_ARCH_TESTING",
50+
androidTestRunner : "com.android.support.test:runner:$ANDROID_TEST_RUNNER",
4751
androidAnnotations : "com.android.support:support-annotations:$ANDROID_SUPPORT_LIBS_VERSION",
4852
dataBindingCompiler : "com.android.databinding:compiler:$ANDROID_PLUGIN_VERSION",
4953
dataBindingAdapters : "com.android.databinding:adapters:$ANDROID_DATA_BINDING",

epoxy-paging/build.gradle

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
apply plugin: 'com.android.library'
2-
2+
apply plugin: 'kotlin-android'
33
android {
44
compileSdkVersion rootProject.COMPILE_SDK_VERSION
55

66
defaultConfig {
77
minSdkVersion rootProject.MIN_SDK_VERSION
88
targetSdkVersion rootProject.TARGET_SDK_VERSION
9+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
910
}
1011
}
1112

1213
dependencies {
14+
implementation rootProject.deps.kotlin
15+
api rootProject.deps.androidPagingComponent
16+
api project(':epoxy-annotations')
17+
api project(':epoxy-adapter')
1318

14-
compile rootProject.deps.androidPagingComponent
15-
compile project(':epoxy-annotations')
16-
compile project(':epoxy-adapter')
19+
androidTestImplementation rootProject.deps.junit
20+
androidTestImplementation rootProject.deps.androidArchCoreTesting
21+
androidTestImplementation rootProject.deps.androidTestRunner
1722

18-
testCompile rootProject.deps.junit
19-
testCompile rootProject.deps.robolectric
20-
testCompile rootProject.deps.mockito
23+
kaptAndroidTest project(":epoxy-processor")
2124
}
2225

2326
apply from: rootProject.file('gradle/gradle-maven-push.gradle')
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2018 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.airbnb.epoxy.paging
17+
18+
import android.support.v7.util.DiffUtil
19+
20+
/**
21+
* Dummy item for testing.
22+
*/
23+
data class Item(val id: Int, val value: String) {
24+
companion object {
25+
val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Item>() {
26+
override fun areItemsTheSame(oldItem: Item, newItem: Item) = oldItem.id == newItem.id
27+
28+
override fun areContentsTheSame(oldItem: Item, newItem: Item) = oldItem == newItem
29+
}
30+
}
31+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright 2018 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.airbnb.epoxy.paging
17+
18+
import android.arch.paging.PositionalDataSource
19+
20+
/**
21+
* Simple data source that works with a given list and its loading can be stopped / started.
22+
*/
23+
class ListDataSource<T>(
24+
private val data: List<T>
25+
) : PositionalDataSource<T>() {
26+
private var pendingActions = arrayListOf<() -> Unit>()
27+
private var running = true
28+
29+
private fun compute(f: () -> Unit) {
30+
if (running) {
31+
f()
32+
} else {
33+
pendingActions.add(f)
34+
}
35+
}
36+
37+
fun start() {
38+
running = true
39+
val pending = pendingActions
40+
pendingActions = arrayListOf()
41+
pending.forEach(this::compute)
42+
}
43+
44+
fun stop() {
45+
running = false
46+
}
47+
48+
override fun loadRange(params: LoadRangeParams, callback: LoadRangeCallback<T>) {
49+
compute {
50+
callback.onResult(
51+
data.subList(params.startPosition, Math.min(data.size, params.startPosition + params.loadSize))
52+
)
53+
}
54+
}
55+
56+
override fun loadInitial(params: LoadInitialParams, callback: LoadInitialCallback<T>) {
57+
val start = computeInitialLoadPosition(params, data.size)
58+
val itemCnt = computeInitialLoadSize(params, start, data.size)
59+
callback.onResult(
60+
data.subList(start, start + itemCnt),
61+
start,
62+
data.size
63+
)
64+
}
65+
}

0 commit comments

Comments
 (0)