どうもかなりお久しぶりです、ヒロです!
qiitaに記事を書くのは壱、十、百、千、満てっじゃなくて万年振りに記事を書きますが、今後はまたライトにメモを残して行こうと思います。
早速本題
通常ScrollViewのonScrollで現在の位置を取得出来ます。
<ScrollView onScroll={e => /* e.nativeEvent.contentOffset.x など*/}>
{images.map(image => <View>{...}</View>)}
</ScrollView>
ここでX軸の割る画面の横幅で現在ScrollViewに表示されている画像が何番目か取得出来ます。
<ScrollView onScroll={e => {
const x = e.nativeEvent.contentOffset.x
// stateに現在のindexを保存。小数点は切り捨て、1枚目を1としたいので1を足す
setCurrentIndex(Math.floor(x / width) + 1)
}>
{images.map(image => <View>{...}</View>)}
</ScrollView>
しかし、Animated.ScrollViewを使っているとこれが出来ないケースがあります。
react-native-animated-scroll-indicatorsのようなライブラリを使っていたりすると、onScrollにこういった記述をする機会が多いでしょう。
const scrollX = new Animated.Value(0);
...
<Animated.ScrollView
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { x: scrollX } } }],
{
useNativeDriver: true,
}
)}
>
...
</Animated.ScrollView>
しかし、この記述をすると先に書いたようなonScrollでxの値を取得する事が出来ません。
そういう場合に
const scrollX = new Animated.Value(0);
...
<Animated.ScrollView
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { x: scrollX } } }],
{
useNativeDriver: true,
// listenerを付与する
listener: (e: NativeSyntheticEvent<NativeScrollEvent>) => {
const offsetX = e.nativeEvent.contentOffset.x;
offsetX / width;
setCurrentIndex(Math.floor(offsetX / width) + 1);
},
}
)}
>
...
</Animated.ScrollView>
上述のように listener を付与するとAnimated.ScrollViewでもスクロール位置を取得出来ます。
特定の画像を表示したら、やスライダーのように何枚目の画像かを表示する際に使えます。
正直Animated.eventの第二引数のオブジェクトにlistenerを付与する事で取得出来るのに辿り着くまで結構苦戦しました。
同じような悩みを抱えている人に届いてくれると嬉しいです。