|
|
@ -47,22 +47,11 @@ fun PullRefresh(
|
|
|
|
content: @Composable () -> Unit,
|
|
|
|
content: @Composable () -> Unit,
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
val state = rememberPullToRefreshState(
|
|
|
|
val state = rememberPullToRefreshState(
|
|
|
|
initialRefreshing = refreshing,
|
|
|
|
isRefreshing = refreshing,
|
|
|
|
extraVerticalOffset = indicatorPadding.calculateTopPadding(),
|
|
|
|
extraVerticalOffset = indicatorPadding.calculateTopPadding(),
|
|
|
|
enabled = enabled,
|
|
|
|
enabled = enabled,
|
|
|
|
|
|
|
|
onRefresh = onRefresh,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
if (state.isRefreshing) {
|
|
|
|
|
|
|
|
LaunchedEffect(true) {
|
|
|
|
|
|
|
|
onRefresh()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
LaunchedEffect(refreshing) {
|
|
|
|
|
|
|
|
if (refreshing && !state.isRefreshing) {
|
|
|
|
|
|
|
|
state.startRefreshAnimated()
|
|
|
|
|
|
|
|
} else if (!refreshing && state.isRefreshing) {
|
|
|
|
|
|
|
|
state.endRefreshAnimated()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Box(modifier.nestedScroll(state.nestedScrollConnection)) {
|
|
|
|
Box(modifier.nestedScroll(state.nestedScrollConnection)) {
|
|
|
|
content()
|
|
|
|
content()
|
|
|
@ -94,10 +83,11 @@ fun PullRefresh(
|
|
|
|
|
|
|
|
|
|
|
|
@Composable
|
|
|
|
@Composable
|
|
|
|
private fun rememberPullToRefreshState(
|
|
|
|
private fun rememberPullToRefreshState(
|
|
|
|
initialRefreshing: Boolean,
|
|
|
|
isRefreshing: Boolean,
|
|
|
|
extraVerticalOffset: Dp,
|
|
|
|
extraVerticalOffset: Dp,
|
|
|
|
positionalThreshold: Dp = 64.dp,
|
|
|
|
positionalThreshold: Dp = 64.dp,
|
|
|
|
enabled: () -> Boolean = { true },
|
|
|
|
enabled: () -> Boolean = { true },
|
|
|
|
|
|
|
|
onRefresh: () -> Unit,
|
|
|
|
): PullToRefreshStateImpl {
|
|
|
|
): PullToRefreshStateImpl {
|
|
|
|
val density = LocalDensity.current
|
|
|
|
val density = LocalDensity.current
|
|
|
|
val extraVerticalOffsetPx = with(density) { extraVerticalOffset.toPx() }
|
|
|
|
val extraVerticalOffsetPx = with(density) { extraVerticalOffset.toPx() }
|
|
|
@ -106,18 +96,29 @@ private fun rememberPullToRefreshState(
|
|
|
|
extraVerticalOffset,
|
|
|
|
extraVerticalOffset,
|
|
|
|
positionalThresholdPx,
|
|
|
|
positionalThresholdPx,
|
|
|
|
enabled,
|
|
|
|
enabled,
|
|
|
|
|
|
|
|
onRefresh,
|
|
|
|
saver = PullToRefreshStateImpl.Saver(
|
|
|
|
saver = PullToRefreshStateImpl.Saver(
|
|
|
|
extraVerticalOffset = extraVerticalOffsetPx,
|
|
|
|
extraVerticalOffset = extraVerticalOffsetPx,
|
|
|
|
positionalThreshold = positionalThresholdPx,
|
|
|
|
positionalThreshold = positionalThresholdPx,
|
|
|
|
enabled = enabled,
|
|
|
|
enabled = enabled,
|
|
|
|
|
|
|
|
onRefresh = onRefresh,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
PullToRefreshStateImpl(
|
|
|
|
PullToRefreshStateImpl(
|
|
|
|
initialRefreshing = initialRefreshing,
|
|
|
|
initialRefreshing = isRefreshing,
|
|
|
|
extraVerticalOffset = extraVerticalOffsetPx,
|
|
|
|
extraVerticalOffset = extraVerticalOffsetPx,
|
|
|
|
positionalThreshold = positionalThresholdPx,
|
|
|
|
positionalThreshold = positionalThresholdPx,
|
|
|
|
enabled = enabled,
|
|
|
|
enabled = enabled,
|
|
|
|
|
|
|
|
onRefresh = onRefresh,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
}.also {
|
|
|
|
|
|
|
|
LaunchedEffect(isRefreshing) {
|
|
|
|
|
|
|
|
if (isRefreshing && !it.isRefreshing) {
|
|
|
|
|
|
|
|
it.startRefreshAnimated()
|
|
|
|
|
|
|
|
} else if (!isRefreshing && it.isRefreshing) {
|
|
|
|
|
|
|
|
it.endRefreshAnimated()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -128,6 +129,7 @@ private fun rememberPullToRefreshState(
|
|
|
|
* @param extraVerticalOffset Extra vertical offset, in pixels, for the "refreshing" state
|
|
|
|
* @param extraVerticalOffset Extra vertical offset, in pixels, for the "refreshing" state
|
|
|
|
* @param initialRefreshing The initial refreshing value of [PullToRefreshState]
|
|
|
|
* @param initialRefreshing The initial refreshing value of [PullToRefreshState]
|
|
|
|
* @param enabled a callback used to determine whether scroll events are to be handled by this
|
|
|
|
* @param enabled a callback used to determine whether scroll events are to be handled by this
|
|
|
|
|
|
|
|
* @param onRefresh a callback to run when pull-to-refresh action is triggered by user
|
|
|
|
* [PullToRefreshState]
|
|
|
|
* [PullToRefreshState]
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private class PullToRefreshStateImpl(
|
|
|
|
private class PullToRefreshStateImpl(
|
|
|
@ -135,6 +137,7 @@ private class PullToRefreshStateImpl(
|
|
|
|
private val extraVerticalOffset: Float,
|
|
|
|
private val extraVerticalOffset: Float,
|
|
|
|
override val positionalThreshold: Float,
|
|
|
|
override val positionalThreshold: Float,
|
|
|
|
enabled: () -> Boolean,
|
|
|
|
enabled: () -> Boolean,
|
|
|
|
|
|
|
|
private val onRefresh: () -> Unit,
|
|
|
|
) : PullToRefreshState {
|
|
|
|
) : PullToRefreshState {
|
|
|
|
|
|
|
|
|
|
|
|
override val progress get() = adjustedDistancePulled / positionalThreshold
|
|
|
|
override val progress get() = adjustedDistancePulled / positionalThreshold
|
|
|
@ -215,6 +218,7 @@ private class PullToRefreshStateImpl(
|
|
|
|
if (isRefreshing) return 0f // Already refreshing, do nothing
|
|
|
|
if (isRefreshing) return 0f // Already refreshing, do nothing
|
|
|
|
// Trigger refresh
|
|
|
|
// Trigger refresh
|
|
|
|
if (adjustedDistancePulled > positionalThreshold) {
|
|
|
|
if (adjustedDistancePulled > positionalThreshold) {
|
|
|
|
|
|
|
|
onRefresh()
|
|
|
|
startRefreshAnimated()
|
|
|
|
startRefreshAnimated()
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
animateTo(0f)
|
|
|
|
animateTo(0f)
|
|
|
@ -263,6 +267,7 @@ private class PullToRefreshStateImpl(
|
|
|
|
extraVerticalOffset: Float,
|
|
|
|
extraVerticalOffset: Float,
|
|
|
|
positionalThreshold: Float,
|
|
|
|
positionalThreshold: Float,
|
|
|
|
enabled: () -> Boolean,
|
|
|
|
enabled: () -> Boolean,
|
|
|
|
|
|
|
|
onRefresh: () -> Unit,
|
|
|
|
) = Saver<PullToRefreshStateImpl, Boolean>(
|
|
|
|
) = Saver<PullToRefreshStateImpl, Boolean>(
|
|
|
|
save = { it.isRefreshing },
|
|
|
|
save = { it.isRefreshing },
|
|
|
|
restore = { isRefreshing ->
|
|
|
|
restore = { isRefreshing ->
|
|
|
@ -271,6 +276,7 @@ private class PullToRefreshStateImpl(
|
|
|
|
extraVerticalOffset = extraVerticalOffset,
|
|
|
|
extraVerticalOffset = extraVerticalOffset,
|
|
|
|
positionalThreshold = positionalThreshold,
|
|
|
|
positionalThreshold = positionalThreshold,
|
|
|
|
enabled = enabled,
|
|
|
|
enabled = enabled,
|
|
|
|
|
|
|
|
onRefresh = onRefresh,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
)
|
|
|
|