假设我有一个主屏幕,其中有许多可点击的卡片,并且我使用 LazyVerticalList 来显示和滚动这些卡片。单击其中一张卡片并导航到其他屏幕然后返回主屏幕后,它将滚动位置重置为最顶部(开始)。
下面是我使用 RememberLazyGridState 的实现
HomeScreen.kt
@Composable
fun HomeScreen(
navController: NavHostController,
darkTheme: Boolean,
onThemeUpdated: () -> Unit,
viewModel: HomeViewModel = viewModel()
) {
val scrollState:LazyGridState = rememberLazyGridState()
viewModel.saveScrollState(scrollState)
Scaffold(
topBar = { TopBar(darkTheme, onThemeUpdated) }
) {
Box(
modifier = Modifier.padding(it)
) {
LazyVerticalGrid(state = scrollState, columns = GridCells.Fixed(2)) {
items(featureList) { (imageId, titleId, routeId) ->
AppScreenCard(
imageId = imageId,
titleId = titleId,
navController = navController,
routeId = routeId
)
}
}
}
}
}
HomeViewModel.kt
class HomeViewModel : ViewModel() {
private val _scrollState = mutableStateOf<LazyGridState?>(null)
val scrollState: State<LazyGridState?> = _scrollState
fun saveScrollState(scrollState: LazyGridState) {
_scrollState.value = scrollState
}
}
貌似不行?
我认为它只是重置了一切。
请尝试以下方法并报告是否适用于您的情况:
首先,向您的 ViewModel 添加两个新属性:
class HomeViewModel () : ViewModel() {
// store the current scroll states
var scrollIndex: Int by mutableStateOf(0)
var scrollOffset: Int by mutableStateOf(0)
}
然后您可以按如下方式访问这两个字段:
@Composable
HomeScreen(viewModel: HomeViewModel = viewModel()) {
val scrollState: LazyGridState = rememberLazyGridState(
viewModel.scrollIndex,
viewModel.scrollOffset
)
// after each scroll, update values in ViewModel
LaunchedEffect(key1 = scrollState.isScrollInProgress) {
if (!scrollState.isScrollInProgress) {
viewModel.scrollIndex = scrollState.firstVisibleItemIndex
viewModel.scrollOffset = scrollState.firstVisibleItemScrollOffset
}
}
}
确保您没有使用新的 ViewModel 实例创建新的 Composable,但这是另一个问题的主题。