From 8ce321b797619a2e809420802f637c880ccb9499 Mon Sep 17 00:00:00 2001 From: HoangChung Date: Tue, 17 May 2022 16:25:53 +0700 Subject: [PATCH 1/3] add callbackFlow loadmore in recyclerview --- .../recyclerview/RecyclerViewLoadMoreFlow.kt | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 flowbinding-recyclerview/src/main/java/reactivecircus/flowbinding/recyclerview/RecyclerViewLoadMoreFlow.kt diff --git a/flowbinding-recyclerview/src/main/java/reactivecircus/flowbinding/recyclerview/RecyclerViewLoadMoreFlow.kt b/flowbinding-recyclerview/src/main/java/reactivecircus/flowbinding/recyclerview/RecyclerViewLoadMoreFlow.kt new file mode 100644 index 000000000..a616816d8 --- /dev/null +++ b/flowbinding-recyclerview/src/main/java/reactivecircus/flowbinding/recyclerview/RecyclerViewLoadMoreFlow.kt @@ -0,0 +1,58 @@ +package reactivecircus.flowbinding.recyclerview + +import androidx.annotation.CheckResult +import androidx.recyclerview.widget.RecyclerView +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.conflate +import reactivecircus.flowbinding.common.checkMainThread + +/** + * Create a [Flow] of scroll events on the [RecyclerView] instance. + * + * Note: create a extension for loading more in different directions + * + * Example of usage: + * + * ``` + * recyclerView.loadMoreFlowVertically() + * .onEach { loadMore -> + * // handle data changed + * } + * .launchIn(uiScope) + * ``` + */ +@CheckResult +@OptIn(ExperimentalCoroutinesApi::class) +public fun RecyclerView.loadMoreFlowVertically(): Flow = callbackFlow { + checkMainThread() + val listener = object : RecyclerView.OnScrollListener() { + override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { + if (!recyclerView.canScrollVertically(1) && newState == RecyclerView.SCROLL_STATE_IDLE) { + trySend(newState) + } + + } + } + addOnScrollListener(listener) + awaitClose { removeOnScrollListener(listener) } +}.conflate() + + +@CheckResult +@OptIn(ExperimentalCoroutinesApi::class) +public fun RecyclerView.loadMoreFlowHorizontally(): Flow = callbackFlow { + checkMainThread() + val listener = object : RecyclerView.OnScrollListener() { + override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { + if (!recyclerView.canScrollHorizontally(1) && newState == RecyclerView.SCROLL_STATE_IDLE) { + trySend(newState) + } + + } + } + addOnScrollListener(listener) + awaitClose { removeOnScrollListener(listener) } +}.conflate() \ No newline at end of file From 209922c70be8df36c742167c78de27a08ac2d550 Mon Sep 17 00:00:00 2001 From: HoangChung Date: Tue, 17 May 2022 16:29:08 +0700 Subject: [PATCH 2/3] add callbackFlow loadmore in recyclerview --- .../recyclerview/RecyclerViewLoadMoreFlow.kt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/flowbinding-recyclerview/src/main/java/reactivecircus/flowbinding/recyclerview/RecyclerViewLoadMoreFlow.kt b/flowbinding-recyclerview/src/main/java/reactivecircus/flowbinding/recyclerview/RecyclerViewLoadMoreFlow.kt index a616816d8..0ed05263b 100644 --- a/flowbinding-recyclerview/src/main/java/reactivecircus/flowbinding/recyclerview/RecyclerViewLoadMoreFlow.kt +++ b/flowbinding-recyclerview/src/main/java/reactivecircus/flowbinding/recyclerview/RecyclerViewLoadMoreFlow.kt @@ -26,14 +26,15 @@ import reactivecircus.flowbinding.common.checkMainThread */ @CheckResult @OptIn(ExperimentalCoroutinesApi::class) -public fun RecyclerView.loadMoreFlowVertically(): Flow = callbackFlow { +public fun RecyclerView.loadMoreFlowVertically(): Flow = callbackFlow { checkMainThread() val listener = object : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { if (!recyclerView.canScrollVertically(1) && newState == RecyclerView.SCROLL_STATE_IDLE) { - trySend(newState) + trySend(true) + } else { + trySend(false) } - } } addOnScrollListener(listener) @@ -43,14 +44,15 @@ public fun RecyclerView.loadMoreFlowVertically(): Flow = callbackFlow { @CheckResult @OptIn(ExperimentalCoroutinesApi::class) -public fun RecyclerView.loadMoreFlowHorizontally(): Flow = callbackFlow { +public fun RecyclerView.loadMoreFlowHorizontally(): Flow = callbackFlow { checkMainThread() val listener = object : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { if (!recyclerView.canScrollHorizontally(1) && newState == RecyclerView.SCROLL_STATE_IDLE) { - trySend(newState) + trySend(true) + } else { + trySend(false) } - } } addOnScrollListener(listener) From df27c5015328992fd030e4e86da329e879c31097 Mon Sep 17 00:00:00 2001 From: hoangchung <52132635+hoangchungk53qx1@users.noreply.github.com> Date: Tue, 17 May 2022 16:30:19 +0700 Subject: [PATCH 3/3] Update README.md --- flowbinding-recyclerview/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flowbinding-recyclerview/README.md b/flowbinding-recyclerview/README.md index 527f8ee2c..f380d59ef 100644 --- a/flowbinding-recyclerview/README.md +++ b/flowbinding-recyclerview/README.md @@ -20,4 +20,6 @@ fun RecyclerView.childAttachStateChangeEvents(): Flow Boolean = { true }): Flow fun RecyclerView.scrollEvents(): Flow fun RecyclerView.scrollStateChanges(): Flow +fun RecyclerView.loadMoreFlowVertically(): Flow +fun RecyclerView.loadMoreFlowHorizontally(): Flow ```