Sorumluluk reddi: Aşağıdakiler öncelikle React Native 0.50'deki kendi deneyimlerimin sonucudur. ScrollView
Dokümantasyon , şu anda aşağıda kaplı birçok bilgi yoktur; örneğin onScrollEndDrag
tamamen belgelenmemiş. Buradaki her şey belgelenmemiş davranışa dayandığından, maalesef bu bilginin şu andan itibaren bir yıl hatta bir ay sonra doğru kalacağına dair hiçbir söz veremem.
Ayrıca, aşağıdaki her şey y ofseti ilgilendiğimiz tamamen dikey bir kaydırma görünümü varsayar ; Gerekirse x ofsetlere çevirmek umarım okuyucu için kolay bir alıştırmadır.
Çeşitli olay işleyicileri ScrollView
alır event
ve geçerli kaydırma konumunu üzerinden almanızı sağlar event.nativeEvent.contentOffset.y
. Bu işleyicilerden bazıları, aşağıda ayrıntılı olarak açıklandığı üzere Android ve iOS arasında biraz farklı davranışa sahiptir.
Android'de
Kullanıcı kaydırırken her kareyi, kullanıcı serbest bıraktıktan sonra kaydırma görünümü kayarken her karede, kaydırma görünümü durduğunda son karede ve ayrıca, çerçevesinin bir sonucu olarak kaydırma görünümünün ofseti değiştiğinde her kareyi ateşler değişiyor (örneğin, yataydan portreye dönüş nedeniyle).
İOS'ta
Kullanıcı sürüklerken veya kaydırma görünümü kayarken, tarafından belirlenen sıklıkta scrollEventThrottle
ve en fazla bir kez ne zaman çerçeve başına bir kez tetiklenir scrollEventThrottle={16}
. Kullanıcı, kaymak için yeterli momentuma sahipken kaydırma görünümünü serbest bırakırsa , onScroll
işleyici, kaymadan sonra dinlenmeye geldiğinde de ateşlenecektir. Kullanıcı sürükler ve sonra sabitken kaydırma görünüm bırakır, ancak onScroll
bir değil sürece nihai konumuna yangına garanti scrollEventThrottle
gibi ayarlanmış olduğunu onScroll
yangınlar kaydırma her çerçevesi.
scrollEventThrottle={16}
Daha büyük bir sayıya ayarlanarak azaltılabilecek bir performans maliyeti vardır . Ancak bu, onScroll
her kareyi ateşlemeyeceği anlamına gelir .
Kaydırdıktan sonra kaydırma görünümü durduğunda ateşlenir. Kullanıcı kaydırma görünümünü sabitken kaymayacak şekilde serbest bırakırsa hiç çalışmaz.
onScrollEndDrag
Kaydırma görünümünün sabit kaldığından veya kaymaya başladığından bağımsız olarak, kullanıcı kaydırma görünümünü sürüklemeyi bıraktığında tetiklenir.
Davranıştaki bu farklılıklar göz önüne alındığında, ofseti takip etmenin en iyi yolu koşullarınıza bağlıdır. En karmaşık durumda ( ScrollView
döndürme nedeniyle çerçevesindeki değişiklikleri işleme dahil olmak üzere Android ve iOS'u desteklemeniz gerekir ve Android'de ayarlardan scrollEventThrottle
16'ya kadar olan performans cezasını kabul etmek istemezsiniz) ve bununla başa çıkmanız gerekir kaydırma görünümündeki içerikte de değişiklik olursa , bu tam bir karmaşa.
En basit durum, yalnızca Android'i kullanmanız gerektiğidir; sadece şunu kullan onScroll
:
<ScrollView
onScroll={event => {
this.yOffset = event.nativeEvent.contentOffset.y
}}
>
Ayrıca iOS desteklemek için, eğer sen sizsiniz, yangın mutlu onScroll
Handler her karesini ve performans etkileri kabul edin ve eğer sen sap çerçeve değişiklikleri gerekmez, o zaman biraz daha karmaşık bit yalnızca var:
<ScrollView
onScroll={event => {
this.yOffset = event.nativeEvent.contentOffset.y
}}
scrollEventThrottle={16}
>
Kaydırma görünümünün yerleştiği herhangi bir konumu kaydetmemizi garanti ederken, iOS'taki performans ek yükünü azaltmak için artırabilir scrollEventThrottle
ve ek olarak bir onScrollEndDrag
işleyici sağlayabiliriz :
<ScrollView
onScroll={event => {
this.yOffset = event.nativeEvent.contentOffset.y
}}
onScrollEndDrag={event => {
this.yOffset = event.nativeEvent.contentOffset.y
}}
scrollEventThrottle={160}
>
Ancak çerçeve değişikliklerini (örneğin, cihazın döndürülmesine izin verdiğimiz için, kaydırma görünümünün çerçevesi için mevcut yüksekliği değiştirdiğimiz için) ve / veya içerik değişikliklerini işlemek istiyorsak, ek olarak her ikisini de uygulamalı onContentSizeChange
ve onLayout
her ikisinin de yüksekliğini takip etmeliyiz kaydırma görünümünün çerçevesi ve içeriği ve böylece sürekli olarak olası maksimum ofseti hesaplayın ve çerçeve veya içerik boyutu değişikliği nedeniyle ofsetin otomatik olarak ne zaman azaldığını tahmin edin:
<ScrollView
onLayout={event => {
this.frameHeight = event.nativeEvent.layout.height;
const maxOffset = this.contentHeight - this.frameHeight;
if (maxOffset < this.yOffset) {
this.yOffset = maxOffset;
}
}}
onContentSizeChange={(contentWidth, contentHeight) => {
this.contentHeight = contentHeight;
const maxOffset = this.contentHeight - this.frameHeight;
if (maxOffset < this.yOffset) {
this.yOffset = maxOffset;
}
}}
onScroll={event => {
this.yOffset = event.nativeEvent.contentOffset.y;
}}
onScrollEndDrag={event => {
this.yOffset = event.nativeEvent.contentOffset.y;
}}
scrollEventThrottle={160}
>
Evet, oldukça korkunç. Ayrıca , kaydırma görünümünün hem çerçevesinin hem de içeriğinin boyutunu aynı anda değiştirdiğiniz durumlarda her zaman doğru çalışacağından% 100 emin değilim . Ancak bulabildiğim en iyisi bu ve bu özellik çerçevenin kendisine eklenene kadar , bence bu herkesin yapabileceği en iyisi.