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
        )
    }
Другие вопросы по тегам