Как я могу прокручивать в обоих направлениях в Jetpack Compose

Я создал довольно классический макет сворачивающегося изображения в Jetpack compose, где у меня есть изображение в верхней части экрана, которое прокручивается от параллакса, и в определенный момент я меняю фон панели инструментов с прозрачного на primarySurface. Все это работает довольно хорошо.

Теперь я хочу иметь пейджер изображений вверху вместо одного, но вертикальная прокрутка поглощает все касания в верхней части экрана. Я пробовал добавить NestedScrollConnection, но мне все еще кажется, что дельта preScroll получается только по одной оси. Я, по-видимому, даже не могу добавить значки в эту область, чтобы выполнить ручную прокрутку пейджера без использования щелчка. Как только я удалю verticalScroll из моего столбца я могу получить события горизонтальной прокрутки для пейджера.

Я использую пейджер Compose 1.0.2, а также библиотеки для врезок.

Это суть существующего кода, в который я хочу добавить пейджер. Как заставить работать пейджер и вертикальную прокрутку?

      val scrollState = rememberScrollState()
Box {
    val imageHeight =
        if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE) 180.dp else 300.dp
    Box {
        // I want to insert a horizontal pager here
        HeaderImage(
            scrollPosition = scrollState.value,
            info = item.heroImages.first(),
            imageHeight = imageHeight
        )
    }
    val appBarHeight = with(LocalDensity.current) { 56.dp.toPx() }
    val scrollHeight = with(LocalDensity.current) { imageHeight.toPx() - appBarHeight }

    Column(
        Modifier
            .verticalScroll(scrollState)
            .padding(top = imageHeight)
            .fillMaxSize()
    ) { ... }
    TopAppBar( ... )

3 ответа

Я только что создал библиотеку для этого. Вы можете прокручивать в обоих направлениях одновременно с этой библиотекой. Однако в настоящее время в нем отсутствует эффект отскока и некоторые другие функции, имеющиеся в официальном модификаторе прокрутки.

Простой пример:

      val scrollState = rememberFreeScrollState()
Column(
    modifier = Modifier
        .fillMaxSize()
        .freeScroll(state = freeScrollState)
) {
    // Content ...
}

Нет проблем с размещением горизонтальной прокрутки внутри вертикальной: прокрутка будет работать без проблем, а текущее направление прокрутки жеста будет выбираться исходя из направления первого перетаскиваемого пикселя.

      Column(
    Modifier
        .verticalScroll(scrollState)
) {
    HorizontalPager(/*...*/)
    OtherScrollableContent(/*...*/)
}

Изменив предыдущий ответ, можно прокручивать в обоих направлениях (но невозможно прокручивать по диагонали):

      val scrollStateHorizontal = rememberScrollState()
val scrollStateVertical = rememberScrollState()

Box(
    modifier = Modifier
        .horizontalScroll(scrollStateHorizontal)
        .verticalScroll(scrollStateVertical)
) {
//Content here
}