Skip to content

Commit

Permalink
Merge pull request #119 from AlanCheen/feature/preload
Browse files Browse the repository at this point in the history
🎨 增加滑动到顶部的预加载功能
  • Loading branch information
AlanCheen authored Oct 8, 2022
2 parents df60013 + 09eb517 commit bd19054
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package me.yifeiyuan.flapdev.testcases

import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import me.yifeiyuan.flap.hook.PreloadHook
import me.yifeiyuan.flapdev.R
import me.yifeiyuan.flapdev.components.SimpleTextModel
import java.util.ArrayList

/**
* Created by 程序亦非猿 on 2021/10/19.
Expand All @@ -28,9 +32,23 @@ class PreloadTestcase : BaseTestcaseFragment() {
}

private fun useAdapter() {
adapter.doOnPreload(offset = 0, minItemCount = 2) {
adapter.doOnPreload(offset = 0, minItemCount = 2, direction = PreloadHook.SCROLL_DOWN) {
requestMoreData()
}

adapter.doOnPreload(offset = 2, minItemCount = 2, direction = PreloadHook.SCROLL_UP) {

toast("顶部,开始预加载")

Handler().postDelayed({
val list = ArrayList<Any>()
val size = 5
repeat(size) {
list.add(SimpleTextModel("头部加载更多数据 $it of $size"))
}
adapter.addDataAndNotify(list)
}, 300)
}
}

private fun requestMoreData() {
Expand All @@ -40,7 +58,7 @@ class PreloadTestcase : BaseTestcaseFragment() {
adapter.setPreloadComplete() // 当出错时,需要手动调用,不然不会再进行检查
} else {
Log.d(TAG, "onViewCreated: 开始预加载")
toast("开始预加载")
toast("底部,开始预加载")
loadMoreData()
}
}
Expand All @@ -62,4 +80,9 @@ class PreloadTestcase : BaseTestcaseFragment() {
}
return super.onOptionsItemSelected(item)
}

override fun onResume() {
super.onResume()
Log.d(TAG, "onResume: ${recyclerView.canScrollVertically(-1)}")
}
}
73 changes: 60 additions & 13 deletions flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ open class FlapAdapter(private val delegation: FlapDelegation = FlapDelegation()
/**
* RecyclerView 滑动到底部触发预加载
*/
private var preloadHook: PreloadHook? = null
private var scrollUpPreloadHook: PreloadHook? = null

private var scrollDownPreloadHook: PreloadHook? = null

/**
* 所有事件的监听
Expand Down Expand Up @@ -85,16 +87,35 @@ open class FlapAdapter(private val delegation: FlapDelegation = FlapDelegation()
inflateWithApplicationContext = Flap.inflateWithApplicationContext
}

// 暂时不需要
// private fun getData(): List<Any> {
// return Collections.unmodifiableList(data)
// }

/**
* 在顶部添加数据
*/
open fun addData(index: Int = 0, dataList: List<Any>) {
data.addAll(index, dataList)
}

open fun addDataAndNotify(dataList: List<Any>, index: Int = 0, byNotifyDataSetChanged: Boolean = false) {
data.addAll(0, dataList)
if (byNotifyDataSetChanged) {
notifyDataSetChanged()
} else {
notifyItemRangeInserted(0, dataList.size)
}
}

open fun setData(newDataList: MutableList<Any>) {
data.clear()
data.addAll(newDataList)
}

open fun <T : Any> setDataAndNotify(newDataList: MutableList<T>, byNotifyDataSetChanged: Boolean = false) {
val preItemCount = itemCount
data.clear()
data.addAll(newDataList)

if (byNotifyDataSetChanged) {
notifyDataSetChanged()
} else {
Expand Down Expand Up @@ -265,25 +286,51 @@ open class FlapAdapter(private val delegation: FlapDelegation = FlapDelegation()
*
* @see PreloadHook
*/
fun doOnPreload(offset: Int = 0, minItemCount: Int = 2, onPreload: () -> Unit) = apply {
preloadHook?.let {
unregisterAdapterHook(it)
}
preloadHook = PreloadHook(offset, minItemCount, onPreload).also {
registerAdapterHook(it)
fun doOnPreload(offset: Int = 0, minItemCount: Int = 2, direction: Int = PreloadHook.SCROLL_DOWN, onPreload: () -> Unit) = apply {
when (direction) {
PreloadHook.SCROLL_UP -> {
scrollUpPreloadHook?.let {
unregisterAdapterHook(it)
}
scrollUpPreloadHook = PreloadHook(offset, minItemCount, direction, onPreload = onPreload).also {
registerAdapterHook(it)
}
}
PreloadHook.SCROLL_DOWN -> {
scrollDownPreloadHook?.let {
unregisterAdapterHook(it)
}
scrollDownPreloadHook = PreloadHook(offset, minItemCount, direction, onPreload = onPreload).also {
registerAdapterHook(it)
}
}
}
}

/**
* 设置是否启用预加载
* 需要先调用 doOnPreload 开启才有效。
*/
fun setPreloadEnable(enable: Boolean) = apply {
preloadHook?.preloadEnable = enable
fun setPreloadEnable(enable: Boolean, direction: Int = PreloadHook.SCROLL_DOWN) = apply {
when (direction) {
PreloadHook.SCROLL_UP -> {
scrollUpPreloadHook?.preloadEnable = enable
}
PreloadHook.SCROLL_DOWN -> {
scrollDownPreloadHook?.preloadEnable = enable
}
}
}

fun setPreloadComplete() {
preloadHook?.setPreloadComplete()
fun setPreloadComplete(direction: Int = PreloadHook.SCROLL_DOWN) {
when (direction) {
PreloadHook.SCROLL_UP -> {
scrollUpPreloadHook?.setPreloadComplete()
}
PreloadHook.SCROLL_DOWN -> {
scrollDownPreloadHook?.setPreloadComplete()
}
}
}

/**
Expand Down
35 changes: 27 additions & 8 deletions flap/src/main/java/me/yifeiyuan/flap/hook/PreloadHook.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,20 @@ import java.util.concurrent.atomic.AtomicBoolean
* @since 2021/9/28
* @since 3.0.0
*/
class PreloadHook(private val offset: Int = 0, private val minItemCount: Int = 2, private val onPreload: () -> Unit) : AdapterHook {
class PreloadHook(private val offset: Int = 0, private val minItemCount: Int = 2, private val direction: Int = SCROLL_DOWN, private val onPreload: () -> Unit) : AdapterHook {

companion object {
private const val TAG = "PreloadHook"

/**
* 向底部滚动,手指往上滑动
*/
const val SCROLL_DOWN = 0

/**
* 向顶部滚动,手指往下滑动
*/
const val SCROLL_UP = 1
}

init {
Expand Down Expand Up @@ -66,17 +76,26 @@ class PreloadHook(private val offset: Int = 0, private val minItemCount: Int = 2
}
}

private var prePosition = -1
override fun onBindViewHolderEnd(adapter: FlapAdapter, delegate: AdapterDelegate<*, *>, component: Component<*>, data: Any, position: Int, payloads: MutableList<Any>) {
val itemCount = adapter.itemCount

if (preloadEnable && itemCount >= minItemCount && position + offset >= itemCount - 1) {
if (loading.get()) {
return
if (preloadEnable && !loading.get()) {
if (direction == SCROLL_DOWN && prePosition < position) {
if (itemCount >= minItemCount && position + offset >= itemCount - 1) {
loading.set(true)
onPreload()
FlapDebug.d(TAG, "滑动到「底部」触发预加载,当前 position = $position,itemCount = $itemCount")
}
} else if (direction == SCROLL_UP && prePosition > position) {
if (itemCount >= minItemCount && position - offset <= 0) {
loading.set(true)
onPreload()
FlapDebug.d(TAG, "滑动到「顶部」触发预加载,当前 position = $position,itemCount = $itemCount")
}
}
loading.set(true)
onPreload()
FlapDebug.d(TAG, "触发预加载,当前 position = $position,itemCount = $itemCount")
}

prePosition = position
}

fun setPreloadComplete() {
Expand Down

0 comments on commit bd19054

Please sign in to comment.