pref: 加载更多防抖

This commit is contained in:
HuanCheng65 2023-07-23 23:00:06 +08:00
parent 5248ce6cf8
commit 7925c36f07
No known key found for this signature in database
GPG Key ID: 5EC9DD60A32C7360
1 changed files with 54 additions and 9 deletions

View File

@ -2,15 +2,30 @@ package com.huanchengfly.tieba.post.ui.widgets.compose
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.FractionalThreshold
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
@ -27,12 +42,17 @@ import androidx.compose.ui.unit.dp
import com.huanchengfly.tieba.post.R
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
import com.huanchengfly.tieba.post.ui.common.theme.compose.loadMoreIndicator
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch
import kotlin.math.abs
import kotlin.math.roundToInt
private val LoadDistance = 70.dp
@OptIn(ExperimentalMaterialApi::class)
@OptIn(ExperimentalMaterialApi::class, FlowPreview::class)
@Composable
fun LoadMoreLayout(
isLoading: Boolean,
@ -50,17 +70,42 @@ fun LoadMoreLayout(
) {
val loadDistance = with(LocalDensity.current) { LoadDistance.toPx() }
val curOnLoadMore by rememberUpdatedState(newValue = onLoadMore)
var lastTriggerTime by remember { mutableStateOf(0L) }
var waitingStateReset by remember { mutableStateOf(false) }
val loadMoreFlow = remember {
MutableSharedFlow<Long>(
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_LATEST
)
}
val coroutineScope = rememberCoroutineScope()
DisposableEffect(Unit) {
val job = coroutineScope.launch {
loadMoreFlow
.sample(500)
.collect {
curOnLoadMore()
waitingStateReset = true
lastTriggerTime = it
}
}
onDispose { job.cancel() }
}
val canLoadMore = remember(enableLoadMore, loadEnd) { enableLoadMore && !loadEnd }
val curIsLoading by rememberUpdatedState(newValue = isLoading)
val curCanLoadMore by rememberUpdatedState(newValue = canLoadMore)
var waitingStateReset by remember { mutableStateOf(false) }
val swipeableState = rememberSwipeableState(false) { newValue ->
if (newValue && !curIsLoading && curCanLoadMore) {
onLoadMore()
waitingStateReset = true
true
val curTime = System.currentTimeMillis()
coroutineScope.launch {
loadMoreFlow.emit(curTime)
}
curTime - lastTriggerTime >= 500
} else !newValue
}
@ -71,6 +116,8 @@ fun LoadMoreLayout(
}
}
LaunchedEffect(isLoading) { swipeableState.animateTo(isLoading) }
Box(
modifier = Modifier
.nestedScroll(swipeableState.LoadPreUpPostDownNestedScrollConnection)
@ -96,8 +143,6 @@ fun LoadMoreLayout(
indicator(isLoading, loadEnd, swipeableState.targetValue)
}
}
LaunchedEffect(isLoading) { swipeableState.animateTo(isLoading) }
}
}