diff --git a/app/src/main/java/me/yifeiyuan/flapdev/testcases/PreloadTestcase.kt b/app/src/main/java/me/yifeiyuan/flapdev/testcases/PreloadTestcase.kt index 98b1440a..8415cdc3 100644 --- a/app/src/main/java/me/yifeiyuan/flapdev/testcases/PreloadTestcase.kt +++ b/app/src/main/java/me/yifeiyuan/flapdev/testcases/PreloadTestcase.kt @@ -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. @@ -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() + val size = 5 + repeat(size) { + list.add(SimpleTextModel("头部加载更多数据 $it of $size")) + } + adapter.addDataAndNotify(list) + }, 300) + } } private fun requestMoreData() { @@ -40,7 +58,7 @@ class PreloadTestcase : BaseTestcaseFragment() { adapter.setPreloadComplete() // 当出错时,需要手动调用,不然不会再进行检查 } else { Log.d(TAG, "onViewCreated: 开始预加载") - toast("开始预加载") + toast("底部,开始预加载") loadMoreData() } } @@ -62,4 +80,9 @@ class PreloadTestcase : BaseTestcaseFragment() { } return super.onOptionsItemSelected(item) } + + override fun onResume() { + super.onResume() + Log.d(TAG, "onResume: ${recyclerView.canScrollVertically(-1)}") + } } \ No newline at end of file diff --git a/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt b/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt index 52baf8f0..87484d9e 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt @@ -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 /** * 所有事件的监听 @@ -85,16 +87,35 @@ open class FlapAdapter(private val delegation: FlapDelegation = FlapDelegation() inflateWithApplicationContext = Flap.inflateWithApplicationContext } + // 暂时不需要 +// private fun getData(): List { +// return Collections.unmodifiableList(data) +// } + + /** + * 在顶部添加数据 + */ + open fun addData(index: Int = 0, dataList: List) { + data.addAll(index, dataList) + } + + open fun addDataAndNotify(dataList: List, index: Int = 0, byNotifyDataSetChanged: Boolean = false) { + data.addAll(0, dataList) + if (byNotifyDataSetChanged) { + notifyDataSetChanged() + } else { + notifyItemRangeInserted(0, dataList.size) + } + } + open fun setData(newDataList: MutableList) { data.clear() data.addAll(newDataList) } open fun setDataAndNotify(newDataList: MutableList, byNotifyDataSetChanged: Boolean = false) { - val preItemCount = itemCount data.clear() data.addAll(newDataList) - if (byNotifyDataSetChanged) { notifyDataSetChanged() } else { @@ -265,12 +286,24 @@ 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) + } + } } } @@ -278,12 +311,26 @@ open class FlapAdapter(private val delegation: FlapDelegation = FlapDelegation() * 设置是否启用预加载 * 需要先调用 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() + } + } } /** diff --git a/flap/src/main/java/me/yifeiyuan/flap/hook/PreloadHook.kt b/flap/src/main/java/me/yifeiyuan/flap/hook/PreloadHook.kt index e0fa91dc..b54e09c7 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/hook/PreloadHook.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/hook/PreloadHook.kt @@ -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 { @@ -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) { 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() {