react-nativereact-native-scrollview

How to scroll to image[x] in ScrollView at the first time open screen?


How to scroll to image[x] in ScrollView at the first time component load?

I want when we open this screen, ScrollView will scroll to the 4th image.

This is my demo

export default function App() {
  const scrollX = useRef(new Animated.Value(0));
  const imageRef = createRef(scrollX);

  useEffect(() => {
    imageRef.current?.scrollTo(new Animated.Value(3));
  }, []);

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.scrollContainer}>
        <ScrollView
          ref={imageRef}
          horizontal={true}
          pagingEnabled
          showsHorizontalScrollIndicator={false}
          onScroll={Animated.event(
            [
              {
                nativeEvent: {
                  contentOffset: {
                    x: scrollX.current,
                  },
                },
              },
            ],
            { useNativeDriver: false }
          )}
          scrollEventThrottle={1}
        >
          {children}
        </ScrollView>
      </View>
    </SafeAreaView>
  );
}

Solution

  • scrollTo accept separate compoenents. You don't need to use animated component and the onScroll method for react scrollview. Just enter {x: value, animated: true} in scrollTo as it accepts object

    Here is the code updated from snack:

    import React, { useRef, useEffect, createRef } from "react";
    import {
      SafeAreaView,
      ScrollView,
      Text,
      StyleSheet,
      View,
      ImageBackground,
      Animated,
      Dimensions,
    } from "react-native";
    
    const images = new Array(6).fill(
      "https://images.unsplash.com/photo-1556740749-887f6717d7e4"
    );
    
    export const WIDTH = Dimensions.get("window").width;
    
    export default function App() {
      const imageRef = useRef();
    
      useEffect(() => {
        imageRef.current?.scrollTo({x: WIDTH * 3});
      },[]);
    
      return (
        <SafeAreaView style={styles.container}>
          <View style={styles.scrollContainer}>
            <ScrollView
              ref={imageRef}
              horizontal={true}
              pagingEnabled
              showsHorizontalScrollIndicator={false}
            >
              {images.map((image, imageIndex) => {
                return (
                  <View
                    style={{
                      width: WIDTH,
                      height: 250,
                    }}
                    key={imageIndex}
                  >
                    <ImageBackground source={{ uri: image }} style={styles.card}>
                      <View style={styles.textContainer}>
                        <Text style={styles.infoText}>
                          {"Image - " + imageIndex}
                        </Text>
                      </View>
                    </ImageBackground>
                  </View>
                );
              })}
            </ScrollView>
          </View>
        </SafeAreaView>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        alignItems: "center",
        justifyContent: "center",
      },
      scrollContainer: {
        height: 300,
        alignItems: "center",
        justifyContent: "center",
      },
      card: {
        flex: 1,
        marginVertical: 4,
        marginHorizontal: 16,
        borderRadius: 5,
        overflow: "hidden",
        alignItems: "center",
        justifyContent: "center",
      },
      textContainer: {
        backgroundColor: "rgba(0,0,0, 0.7)",
        paddingHorizontal: 24,
        paddingVertical: 8,
        borderRadius: 5,
      },
      infoText: {
        color: "white",
        fontSize: 16,
        fontWeight: "bold",
      },
    });