Можно ли получить текущую позицию прокрутки или текущую страницу <ScrollView>
компонента в React Native?
Так что-то вроде:
<ScrollView
horizontal={true}
pagingEnabled={true}
onScrollAnimationEnd={() => {
// get this scrollview's current page or x/y scroll position
}}>
this.state.data.map(function(e, i) {
<ImageCt key={i}></ImageCt>
})
</ScrollView>
ios
reactjs
react-native
Sang
источник
источник
Ответы:
Пытаться.
А потом:
источник
event.nativeEvent.contentOffset.x
если у вас есть горизонтальный ScrollView;) Спасибо!scrollEventThrottle
значение 16 или ниже (чтобы получать событие для каждого кадра), нет никакой гарантии, что это будет сообщать смещение в последнем кадре - это означает, что для уверенности в правильном смещении после завершения прокрутки, вам необходимо установитьscrollEventThrottle={16}
и принять влияние этого на производительность.event.nativeEvent.contentOffset.y
?Отказ от ответственности: все, что следует ниже, в первую очередь является результатом моих собственных экспериментов с React Native 0.50. В
ScrollView
документации в настоящее время отсутствует большая часть информации, описанной ниже; напримерonScrollEndDrag
, полностью недокументировано. Поскольку все здесь основано на недокументированном поведении, я, к сожалению, не могу обещать, что эта информация останется верной через год или даже через месяц.Кроме того, все, что ниже, предполагает чисто вертикальную прокрутку, чье смещение по y нас интересует; перевод в x смещения, если необходимо, будет легким упражнением для читателя.
Различные обработчики событий на
ScrollView
Берутevent
и позволяют получить текущую позицию прокрутки с помощьюevent.nativeEvent.contentOffset.y
. Некоторые из этих обработчиков немного различаются между Android и iOS, как описано ниже.onScroll
На Android
Запускает каждый кадр, пока пользователь прокручивает, на каждом кадре, когда представление прокрутки скользит после того, как пользователь отпускает его, на последнем кадре, когда представление прокрутки останавливается, а также всякий раз, когда смещение представления прокрутки изменяется в результате его кадра изменение (например, из-за поворота с пейзажа на портрет).
На iOS
Срабатывает, когда пользователь перетаскивает или скользит вид прокрутки, с некоторой частотой, определяемой
scrollEventThrottle
и не более одного раза за кадр, когдаscrollEventThrottle={16}
. Если пользователь отпускает режим прокрутки, пока у него достаточно импульса для скольжения,onScroll
обработчик также сработает, когда он остановится после скольжения. Однако, если пользователь перетаскивает , а затем отпускает вид прокрутки , пока она находится в неподвижном состоянии ,onScroll
это не гарантирует огня для конечной позиции , еслиscrollEventThrottle
не было установлено , что такиеonScroll
пожары каждый кадр прокрутки.Установка
scrollEventThrottle={16}
требует снижения производительности, которую можно уменьшить, задав большее значение. Однако это означает, чтоonScroll
не будет запускаться каждый кадр.onMomentumScrollEnd
Срабатывает, когда режим прокрутки останавливается после скольжения. Не срабатывает вообще, если пользователь отпускает прокрутку, когда она неподвижна и не скользит.
onScrollEndDrag
Срабатывает, когда пользователь перестает перетаскивать вид прокрутки - независимо от того, остается ли вид прокрутки неподвижным или начинает скользить.
Учитывая эти различия в поведении, лучший способ отслеживать смещение зависит от конкретных обстоятельств. В самом сложном случае (вам необходимо поддерживать Android и iOS, в том числе обрабатывать изменения в
ScrollView
кадре из-за вращения, и вы не хотите соглашаться с потерей производительности на Android при установкеscrollEventThrottle
на 16), и вам нужно обработать тоже меняет содержимое в режиме прокрутки, то это чертовски беспорядок.Самый простой случай - если вам нужно работать только с Android; просто используйте
onScroll
:Для дополнительной поддержки iOS, если вы счастливы запускать
onScroll
обработчик каждого кадра и принимать последствия этого для производительности, и если вам не нужно обрабатывать изменения кадра, тогда это только немного сложнее:Чтобы уменьшить накладные расходы на производительность на iOS, при этом гарантируя, что мы записываем любую позицию, на которой устанавливается представление прокрутки, мы можем увеличить
scrollEventThrottle
и дополнительно предоставитьonScrollEndDrag
обработчик:Но если мы хотим обрабатывать изменения кадра (например, потому что мы позволяем вращать устройство, изменяя доступную высоту для кадра просмотра прокрутки) и / или изменения содержимого, то мы должны дополнительно реализовать оба
onContentSizeChange
иonLayout
отслеживать высоту обоих фрейм представления прокрутки и его содержимое, и, таким образом, непрерывно вычислять максимально возможное смещение и делать вывод о том, когда смещение было автоматически уменьшено из-за изменения фрейма или размера содержимого:Да, это довольно ужасно. Я также не уверен на 100%, что он всегда будет работать правильно в тех случаях, когда вы одновременно изменяете размер как рамки, так и содержимого представления прокрутки. Но это лучшее, что я могу придумать, и пока эта функция не будет добавлена в сам фреймворк , я думаю, что это лучшее, что может сделать каждый.
источник
Ответ Брэда Ойлера правильный. Но вы получите только одно событие. Если вам нужно получать постоянные обновления позиции прокрутки, вы должны установить
scrollEventThrottle
опору, например:И обработчик событий:
Имейте в виду, что вы можете столкнуться с проблемами производительности. Отрегулируйте дроссельную заслонку соответствующим образом. 16 дает вам больше всего обновлений. 0 только один.
источник
function(event) { }
.scrollEventThrottle={16}
это не даст вам «меньше» обновления; любое число в диапазоне 1–16 дает максимально возможную скорость обновления. Значение по умолчанию 0 дает вам (в iOS) одно событие, когда пользователь начинает прокрутку, а затем никаких последующих обновлений (что довольно бесполезно и, возможно, является ошибкой); по умолчанию это не «один раз за кадр». Помимо этих двух ошибок в вашем комментарии, другие ваши утверждения не противоречат тому, что говорится в ответе (хотя вы, кажется, думаете, что они противоречат).Если вы хотите просто получить текущую позицию (например, при нажатии какой-либо кнопки), а не отслеживать ее всякий раз, когда пользователь прокручивает, то вызов
onScroll
слушателя вызовет проблемы с производительностью. В настоящее время наиболее эффективный способ просто получить текущую позицию прокрутки - использовать пакет response-native-invoke . Есть пример именно этой вещи, но пакет выполняет еще несколько вещей.Об этом читайте здесь. https://medium.com/@talkol/invoke-any-native-api-directly-from-pure-javascript-in-react-native-1fb6afcdf57d#.68ls1sopd
источник
Чтобы получить x / y после завершения прокрутки, как запрашивали исходные вопросы, возможно, самый простой способ:
источник
onMomentumScrollEnd
запускается только в том случае, если просмотр прокрутки имеет некоторый импульс, когда пользователь отпускает его. Если они отпустят, пока ползунок не движется, вы никогда не получите ни одного события импульса.Приведенные выше ответы рассказывают, как получить позицию, используя другой API
onScroll
иonMomentumScrollEnd
т. Д .; Если вы хотите узнать индекс страницы, вы можете рассчитать его, используя значение смещения.В iOS отношения между ScrollView и видимой областью следующие:
ссылка: https://www.objc.io/issues/3-views/scroll-view/
источник
Вот как закончилось получение текущей позиции прокрутки в реальном времени из представления. Все, что я делаю, это использую прослушиватель событий при прокрутке и scrollEventThrottle. Затем я передаю его как событие для обработки созданной мной функции прокрутки и обновления моих реквизитов.
источник
использование onScroll входит в бесконечный цикл. Вместо этого можно использовать onMomentumScrollEnd или onScrollEndDrag
источник
Что касается страницы, я работаю над компонентом более высокого порядка, который использует в основном вышеуказанные методы для выполнения именно этого. На самом деле это займет совсем немного времени, если вы перейдете к таким тонкостям, как первоначальный макет и изменение содержимого. Я не буду утверждать, что сделал это «правильно», но в некотором смысле я бы посчитал правильным ответом использовать компонент, который делает это осторожно и последовательно.
Смотрите: response-native-paged-scroll-view . Хотел бы получить обратную связь, даже если я все сделал неправильно!
источник
Я считаю,
contentOffset
что даст вам объект, содержащий смещение прокрутки вверху слева:http://facebook.github.io/react-native/docs/scrollview.html#contentoffset
источник