Fix rememberOverscrollEffect compat for legacy build

The legacy build (API 21) uses Compose BOM 2025.01.00 where
rememberOverscrollEffect() is internal and overscrollEffect
parameter doesn't exist on verticalScroll/LazyColumn.
This commit is contained in:
世界
2026-02-05 20:26:02 +08:00
parent eaff2af1e7
commit 02f9ec4d97
5 changed files with 131 additions and 10 deletions

View File

@@ -11,10 +11,8 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberOverscrollEffect
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.MoreVert
@@ -46,6 +44,8 @@ import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
import io.nekohasekai.libbox.Libbox
import io.nekohasekai.sfa.R
import io.nekohasekai.sfa.compat.rememberOverscrollEffectCompat
import io.nekohasekai.sfa.compat.verticalScrollCompat
import io.nekohasekai.sfa.compose.model.Connection
import io.nekohasekai.sfa.compose.util.rememberSheetDismissFromContentOnlyIfGestureStartedAtTopModifier
import java.text.SimpleDateFormat
@@ -77,7 +77,7 @@ fun ConnectionDetailsScreen(
modifier = modifier
.fillMaxSize()
.then(scrollModifier)
.verticalScroll(scrollState, overscrollEffect = if (asSheet) null else rememberOverscrollEffect()),
.verticalScrollCompat(scrollState, overscrollEffect = if (asSheet) null else rememberOverscrollEffectCompat()),
) {
if (showHeader) {
Row(

View File

@@ -17,7 +17,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberOverscrollEffect
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Check
@@ -59,6 +58,8 @@ import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import io.nekohasekai.sfa.R
import io.nekohasekai.sfa.compat.LazyColumnCompat
import io.nekohasekai.sfa.compat.rememberOverscrollEffectCompat
import io.nekohasekai.sfa.compose.model.Connection
import io.nekohasekai.sfa.compose.model.ConnectionSort
import io.nekohasekai.sfa.compose.model.ConnectionStateFilter
@@ -401,7 +402,7 @@ fun ConnectionsScreen(
lazyListState.firstVisibleItemIndex == 0 &&
lazyListState.firstVisibleItemScrollOffset == 0
}
LazyColumn(
LazyColumnCompat(
modifier =
modifier
.fillMaxSize()
@@ -556,7 +557,7 @@ fun ConnectionsScreen(
else -> {
val bounceBlockingConnection = rememberBounceBlockingNestedScrollConnection(lazyListState)
LazyColumn(
LazyColumnCompat(
modifier =
Modifier
.fillMaxSize()
@@ -564,7 +565,7 @@ fun ConnectionsScreen(
state = lazyListState,
contentPadding = PaddingValues(start = 16.dp, end = 16.dp, bottom = 16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
overscrollEffect = rememberOverscrollEffect(),
overscrollEffect = rememberOverscrollEffectCompat(),
) {
items(
items = uiState.connections,

View File

@@ -23,7 +23,6 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberOverscrollEffect
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ExpandMore
@@ -67,6 +66,8 @@ import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.compose.viewModel
import io.nekohasekai.libbox.Libbox
import io.nekohasekai.sfa.R
import io.nekohasekai.sfa.compat.LazyColumnCompat
import io.nekohasekai.sfa.compat.rememberOverscrollEffectCompat
import io.nekohasekai.sfa.compose.model.Group
import io.nekohasekai.sfa.compose.model.GroupItem
import io.nekohasekai.sfa.compose.screen.dashboard.groups.GroupsViewModel
@@ -199,9 +200,9 @@ private fun GroupsCardContent(
} else {
Modifier.nestedScroll(rememberBounceBlockingNestedScrollConnection(lazyListState))
}
val overscrollEffect = if (asSheet) null else rememberOverscrollEffect()
val overscrollEffect = if (asSheet) null else rememberOverscrollEffectCompat()
LazyColumn(
LazyColumnCompat(
modifier =
modifier
.fillMaxSize()

View File

@@ -0,0 +1,56 @@
package io.nekohasekai.sfa.compat
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.gestures.FlingBehavior
import androidx.compose.foundation.gestures.ScrollableDefaults
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun rememberOverscrollEffectCompat(): Any? = null
@Suppress("UNUSED_PARAMETER")
@Composable
fun Modifier.verticalScrollCompat(
state: ScrollState,
enabled: Boolean = true,
flingBehavior: FlingBehavior? = null,
reverseScrolling: Boolean = false,
overscrollEffect: Any? = null,
): Modifier = this.verticalScroll(state, enabled, flingBehavior, reverseScrolling)
@Suppress("UNUSED_PARAMETER")
@Composable
fun LazyColumnCompat(
modifier: Modifier = Modifier,
state: LazyListState = rememberLazyListState(),
contentPadding: PaddingValues = PaddingValues(0.dp),
reverseLayout: Boolean = false,
verticalArrangement: Arrangement.Vertical = if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
userScrollEnabled: Boolean = true,
overscrollEffect: Any? = null,
content: LazyListScope.() -> Unit,
) {
LazyColumn(
modifier = modifier,
state = state,
contentPadding = contentPadding,
reverseLayout = reverseLayout,
verticalArrangement = verticalArrangement,
horizontalAlignment = horizontalAlignment,
flingBehavior = flingBehavior,
userScrollEnabled = userScrollEnabled,
content = content,
)
}

View File

@@ -0,0 +1,63 @@
package io.nekohasekai.sfa.compat
import androidx.compose.foundation.OverscrollEffect
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.gestures.FlingBehavior
import androidx.compose.foundation.gestures.ScrollableDefaults
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberOverscrollEffect
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun rememberOverscrollEffectCompat(): OverscrollEffect? = rememberOverscrollEffect()
@Composable
fun Modifier.verticalScrollCompat(
state: ScrollState,
enabled: Boolean = true,
flingBehavior: FlingBehavior? = null,
reverseScrolling: Boolean = false,
overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),
): Modifier = this.verticalScroll(
state = state,
enabled = enabled,
flingBehavior = flingBehavior,
reverseScrolling = reverseScrolling,
overscrollEffect = overscrollEffect,
)
@Composable
fun LazyColumnCompat(
modifier: Modifier = Modifier,
state: LazyListState = rememberLazyListState(),
contentPadding: PaddingValues = PaddingValues(0.dp),
reverseLayout: Boolean = false,
verticalArrangement: Arrangement.Vertical = if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
userScrollEnabled: Boolean = true,
overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),
content: LazyListScope.() -> Unit,
) {
LazyColumn(
modifier = modifier,
state = state,
contentPadding = contentPadding,
reverseLayout = reverseLayout,
verticalArrangement = verticalArrangement,
horizontalAlignment = horizontalAlignment,
flingBehavior = flingBehavior,
userScrollEnabled = userScrollEnabled,
overscrollEffect = overscrollEffect,
content = content,
)
}