pref: 加载更多防抖
This commit is contained in:
parent
5248ce6cf8
commit
7925c36f07
|
|
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue