Jetpack Compose - восстановление состояния прокрутки LazyColumn
У меня есть несколько файлов. По старинке вложенный RecyclerView.
Моя проблема в том, что не восстанавливает состояние прокрутки при переходе к новому составному элементу (Другая вкладка). Но внутренние восстанавливают свое состояние.
Например, откройте главный экран, прокрутите вниз, затем прокрутите до конца, затем откройте другую вкладку и снова вернитесь на главную вкладку. начинается сверху (не восстанавливает состояние), но последний восстанавливает его состояние прокрутки.
Главный экран, содержащий
@Composable
fun HomeScreen(
homeViewModel: HomeViewModel = hiltViewModel()
) {
val scrollState = rememberLazyListState()
LazyColumn(contentPadding = PaddingValues(vertical = 8.dp),
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.spacedBy(8.dp),
state = scrollState,
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colors.background)
) {
items(5) {
TopRatedProducts(homeViewModel = homeViewModel)
}
}
}
TopRatedProducts, содержащий
LazyRow
@Composable
fun TopRatedProducts(
homeViewModel: HomeViewModel = hiltViewModel()
) {
val topRatedProducts by rememberFlowWithLifecycle(homeViewModel.topRatedProducts)
.collectAsState(initial = emptyList())
LazyRow(
contentPadding = PaddingValues(horizontal = 8.dp), // Space between start and end
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp), // Space between items
modifier = Modifier
.background(Color.Green)
) {
items(topRatedProducts) {
ProductCardItem(item = it)
}
}
}
Как я могу восстановить
LazyColumn
состояние прокрутки?
2 ответа
Вы должны упомянуть ViewCompositionStrategy, если хотите, чтобы такое поведение было с ComposeView in Fragments .
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return ComposeView(requireContext()).apply {
// Dispose the Composition when viewLifecycleOwner is destroyed
setViewCompositionStrategy(
ViewCompositionStrategy.DisposeOnLifecycleDestroyed(viewLifecycleOwner)
)
setContent {
// content
}
}
}
Из документации: по умолчанию Compose удаляет композицию всякий раз, когда представление отсоединяется от окна. Типы Compose UI View, такие как ComposeView и AbstractComposeView, используют ViewCompositionStrategy, который определяет это поведение.
По умолчанию Compose использует стратегию DisposeOnDetachedFromWindow. Однако это значение по умолчанию может быть нежелательным в некоторых ситуациях, когда типы представления Compose UI View используются в:
Фрагменты. Композиция должна следовать жизненному циклу представления фрагмента для типов Compose UI View для сохранения состояния.
Переходы. Каждый раз, когда Compose UI View используется как часть перехода, он будет отсоединен от своего окна, когда переход начинается, а не когда переход заканчивается, что заставляет ваш составной объект избавиться от своего состояния, пока он все еще находится на экране.
Держатели представлений RecyclerView или ваше собственное настраиваемое представление, управляемое жизненным циклом
Ссылка на документы: https://developer.android.com/jetpack/compose/interop/interop-apis#composition-strategy
Попробуйте следующее в конце вашего
LaunchedEffect(scrollState.firstVisibleItemScrollOffset) {
scrollState.scrollToItem(
scrollState.firstVisibleItemIndex,
scrollState.firstVisibleItemScrollOffset
)
}