Ojay
Ojay

Reputation: 703

ScrollView programmatically scroll on button press in react native

So I manually created an onboarding screen in React Native using ScrollView and also I added a button labeled next to enable the hidden screen to move in on the screen, Now my challenge is how I can programmatically make my ScrollView Scroll when the button is pressed. Below is my sample functional component I tried my hand at, but I have no idea how I'll go about implementing the button press scroll

export default function Onbaording({ navigation }) {
  const [sliderState, setSliderState] = React.useState({ currentPage: 0 });
  const { width, height } = Dimensions.get("window");

  const setSliderPage = (event) => {
    const { currentPage } = sliderState;
    const { x } = event.nativeEvent.contentOffset;
    const indexOfNextScreen = Math.floor(x / width);
    if (indexOfNextScreen !== currentPage) {
      setSliderState({
        ...sliderState,
        currentPage: indexOfNextScreen,
      });
    }
  };

  const { currentPage: pageIndex } = sliderState;

  return (
    <View style={Styles.container}>
      <SafeAreaView style={{ flex: 4 }}>
        <ScrollView
          horizontal={true}
          scrollEventThrottle={16}
          pagingEnabled={true}
          showsHorizontalScrollIndicator={false}
          snapToStart={true}
          onScroll={(event: any) => {
            setSliderPage(event);
          }}
        >
          <View style={{ width, height, paddingHorizontal: 16 }}>
            <View style={Styles.Svg}>
              <WelcomeSvg1 />
            </View>

            <Text style={Styles.text}>Onboarding</Text>
            <Text>
              Done with React Native.
            </Text>
          </View>

          <View style={{ width, paddingHorizontal: 16 }}>
            <View style={Styles.Svg}>
              <WelcomeSvg2 />
            </View>

            <Text style={Styles.text}>Onboarding</Text>
            <Text>
              Done with React Native.
            </Text>
          </View>
        </ScrollView>


          <View style={Styles.paginationWrapper}>
            {Array.from(Array(2).keys()).map((key, index) => (
              <View
                style={[
                  Styles.paginationDots,
                  {
                    backgroundColor:
                      pageIndex === index ? "#51668F" : "#EAEAEA",
                  },
                ]}
                key={index}
              />
            ))}
          </View>
      </SafeAreaView>

      <View>
          <View
            style={{ flexDirection: "row", justifyContent: "space-between" }}
          >
            <TouchableOpacity
              onPress={() => {
                navigation.navigate("Signin");
              }}
            >
              <Text>Skip</Text>
            </TouchableOpacity>

            <TouchableOpacity>
              <Text>Next</Text>
            </TouchableOpacity>
          </View>
      </View>
    </View>
  );
}

Upvotes: 14

Views: 22055

Answers (1)

Kipnoedels
Kipnoedels

Reputation: 1365

You can assign a ref to your ScrollView. This ref contains a function called scrollTo().

First define the ref: const scrollViewRef = useRef(null); (https://react.dev/reference/react/useRef#useref)

Next add the ref to your ScrollView:

<ScrollView
   ref={scrollViewRef}
>
</ScrollView>

Now all we need to do is scroll the ScrollView to the desired position. There are multiple ways to do this. I like to keep track of the page index / number to calculate the next scroll position. You could also use a FlatList.

So you could do something like this on your TouchableOpacity around Next:

const toNextPage = () => {
   screenIndex += 1;
   scrollViewRef.current?.scrollTo({x: window.width * screenIndex, animated: true});
};

onPress={toNextPage}

See https://reactnative.dev/docs/scrollview#scrollto for more info about scrollTo()

Upvotes: 23

Related Questions