@@ -2,6 +2,7 @@ package li.songe.gkd.ui.component
22
33import androidx.compose.animation.core.AnimationConstants.DefaultDurationMillis
44import androidx.compose.foundation.ScrollState
5+ import androidx.compose.foundation.gestures.ScrollableState
56import androidx.compose.foundation.layout.height
67import androidx.compose.foundation.layout.width
78import androidx.compose.foundation.lazy.LazyListState
@@ -15,7 +16,6 @@ import androidx.compose.runtime.LaunchedEffect
1516import androidx.compose.runtime.ReadOnlyComposable
1617import androidx.compose.runtime.collectAsState
1718import androidx.compose.runtime.derivedStateOf
18- import androidx.compose.runtime.key
1919import androidx.compose.runtime.remember
2020import androidx.compose.runtime.rememberCoroutineScope
2121import androidx.compose.ui.Modifier
@@ -74,32 +74,51 @@ private fun getCompatStateValue(v: Any?): Any? = when (v) {
7474 else -> v
7575}
7676
77- // key 函数的依赖变化时, compose 将重置 key 函数那行代码之后所有代码的状态, 因此需要需要将 key 作用域限定在 Composable fun 内
78- // 所有的 key 参数必须使用 rememberSaveable 或者 viewModel 来保存状态, 以保证正确的 restore 顺序,否则触发 ClassCastException
7977@Composable
8078fun useListScrollState (
8179 v1 : Any? ,
8280 v2 : Any? = null,
8381 v3 : Any? = null,
8482 canScroll : () -> Boolean = { true },
8583): Pair <TopAppBarScrollBehavior , LazyListState > {
86- return key(
87- getCompatStateValue(v1),
88- getCompatStateValue(v2),
89- getCompatStateValue(v3),
90- ) {
91- TopAppBarDefaults .enterAlwaysScrollBehavior(canScroll = canScroll) to rememberLazyListState()
84+ val scrollBehavior = TopAppBarDefaults .enterAlwaysScrollBehavior(canScroll = canScroll)
85+ val scrollState = rememberLazyListState()
86+ LaunchedEffect (getCompatStateValue(v1), getCompatStateValue(v2), getCompatStateValue(v3)) {
87+ resetScroll(scrollBehavior, scrollState)
9288 }
89+ return scrollBehavior to scrollState
9390}
9491
9592@Composable
9693fun usePinnedScrollBehaviorState (v1 : Any? ): Pair <TopAppBarScrollBehavior , LazyListState > {
97- return key(getCompatStateValue(v1)) { TopAppBarDefaults .pinnedScrollBehavior() to rememberLazyListState() }
94+ val scrollBehavior = TopAppBarDefaults .pinnedScrollBehavior()
95+ val scrollState = rememberLazyListState()
96+ LaunchedEffect (getCompatStateValue(v1)) {
97+ resetScroll(scrollBehavior, scrollState)
98+ }
99+ return scrollBehavior to scrollState
98100}
99101
100102@Composable
101103fun useScrollBehaviorState (v1 : Any? ): Pair <TopAppBarScrollBehavior , ScrollState > {
102- return key(getCompatStateValue(v1)) { TopAppBarDefaults .enterAlwaysScrollBehavior() to rememberScrollState() }
104+ val scrollBehavior = TopAppBarDefaults .enterAlwaysScrollBehavior()
105+ val scrollState = rememberScrollState()
106+ LaunchedEffect (getCompatStateValue(v1)) {
107+ resetScroll(scrollBehavior, scrollState)
108+ }
109+ return scrollBehavior to scrollState
110+ }
111+
112+ private suspend fun resetScroll (
113+ scrollBehavior : TopAppBarScrollBehavior ,
114+ scrollState : ScrollableState ,
115+ ) {
116+ when (scrollState) {
117+ is LazyListState -> scrollState.scrollToItem(0 )
118+ is ScrollState -> scrollState.scrollTo(0 )
119+ }
120+ scrollBehavior.state.heightOffset = 0f
121+ scrollBehavior.state.contentOffset = 0f
103122}
104123
105124@Composable
0 commit comments