Прокрутка делится на несколько этапов. Дельта ввода отправляется через последовательность фаз, чтобы гарантировать, что у каждой фазы есть возможность использовать движение или реагировать на него.
На протяжении всего цикла на каждом шаге передаются как доступная, так и использованная дельта входных данных. Это обеспечивает каждую фазу полным контекстом, необходимым для реагирования на событие прокрутки, его использования или прослушивания.
Как показано на рисунке 1, процесс прокрутки происходит в следующем порядке:
- Overscroll. Сначала получает начальную дельту ввода, что дает возможность отреагировать первым (например, за счет ослабления активного эффекта растяжения).
- Предварительная прокрутка вложенного элемента. Позволяет реагировать на дельту ввода до фазы прокрутки. На этом этапе может быть использована некоторая дельта ввода или она может просто отслеживаться для запуска изменений пользовательского интерфейса, таких как сворачивание или развертывание панели приложения.
- Преобразование дельты ввода. Корректирует знак необработанной дельты ввода на основе ориентации и направления макета, чтобы обеспечить естественное поведение прокрутки. Подробную информацию вы найдете в разделе Преобразование дельты ввода.
- Прокрутка. На этом этапе доступная, неиспользованная дельта ввода корректируется в соответствии с конфигурацией контейнера прокрутки. Обычно это значение используется для обновления смещения прокрутки.
- Revert to raw input delta (Вернуться к исходному изменению ввода). Возвращает доступное и использованное изменение из фазы Scroll (Прокрутка) к исходному знаку изменения ввода.
- Вложенная прокрутка после прокрутки. Эта фаза реагирует после завершения основной фазы прокрутки, получая вновь обновленные доступные и потребленные дельты. Она может использовать любые оставшиеся доступные входные данные или контекст того, что только что было использовано.
- Эффект достижения конца прокрутки. На этом этапе рассматриваются последние доступные и использованные дельты. Любые оставшиеся доступные входные данные, которые доходят до этой стадии, обычно используются для создания краевых эффектов, таких как растяжение или свечение, указывающих на то, что пользователь достиг границы прокручиваемой области.
Преобразовать дельту ввода
Для дельты ввода указателя требуется корректировка знака на разных этапах прокрутки, чтобы соответствовать ожидаемым контрактам. Прежде чем дельта достигнет фазы Прокрутка, модификаторы прокрутки корректируют входную дельту на основе ориентации, направления макета и контекстов RTL. Это происходит потому, что необработанные входные данные отслеживают физическое перемещение пикселей указателя на экране (например, перемещение вниз увеличивает координату Y экрана, что дает положительную дельту). Однако для достижения "естественной прокрутки", когда контент перемещается вместе с пальцем, перетаскивание вниз означает, что область просмотра должна смещаться вверх по контенту, что соответствует отрицательному смещению прокрутки.
Дельты ввода из других источников, таких как колесо мыши или сенсорная панель, не преобразуются на этапах прокрутки.
Пример: указатель перемещается вправо с помощью Modifier.horizontalScroll()
Чтобы понять, как используются и преобразуются дельты, посмотрите на рисунок 2, на котором показан жест, когда указатель перемещается вправо.
- До прокрутки. Жест начинается с положительного необработанного входного значения дельты, равного 100.
- Overscroll наблюдает за этим и потребляет 10, оставляя 90.
- Предварительная прокрутка вложенной прокрутки дает родительскому компоненту возможность отреагировать, потребляя 30. Оставшаяся необработанная разница – 60.
- Преобразование А. Перед переходом к этапу прокрутки
horizontalScrollпреобразует оставшуюся положительную необработанную разницу (60) в отрицательную (-60). Это гарантирует, что область просмотра сдвинется влево, а контент – вправо, вслед за пальцем пользователя. - Прокрутка. Целевой прокручиваемый компонент использует часть этого преобразованного дельта-значения, чтобы обновить смещение прокрутки. В нашем примере это -30. Остается -30.
- Преобразование Б. Неиспользованная дельта прокрутки (-30) преобразуется обратно в положительную необработанную дельту (30), чтобы соответствовать контракту вложенной прокрутки и прокрутки за пределы экрана.
- После прокрутки. Оставшаяся необработанная дельта передается обратно в конвейер.
- Вложенная прокрутка после прокрутки потребляет 10, оставляя 20.
- Эффект достижения конца прокрутки использует последние 20, чтобы создать визуальные эффекты по краям, например растяжение или свечение, полностью разрешая дельту ввода до 0.
Ссылка на преобразование дельты ввода указателя
В таблице ниже показано, как подписываются дельты ввода на разных этапах и в разных направлениях для ввода указателя.
| Разница необработанных входных данных | Эффект достижения конца прокрутки | Вложенная прокрутка | scrollableArea с горизонтальной ориентацией |
scrollableArea с горизонтальной ориентацией (перевернуто) |
scrollableArea с вертикальной ориентацией |
scrollableArea с вертикальной ориентацией (перевернутый) |
|
|---|---|---|---|---|---|---|---|
| Указатель перемещается вверх. | Отрицательные | Отрицательные | Отрицательные | Н/Д | Н/Д | Положительные | Отрицательные |
| Указатель перемещается вниз. | Положительные | Положительные | Положительные | Н/Д | Н/Д | Отрицательные | Положительные |
| Указатель перемещается влево. | Отрицательные | Отрицательные | Отрицательные | Положительное (отрицательное для языков с письмом справа налево) | Отрицательное (положительное для языков с письмом справа налево) | Н/Д | Н/Д |
| Указатель перемещается ВПРАВО. | Положительные | Положительные | Положительные | Отрицательное (положительное для языков с письмом справа налево) | Положительное (отрицательное для языков с письмом справа налево) | Н/Д | Н/Д |