ifelsething logoifelsething

Start Scroll from Different Position in React Native

Published On: 2024-05-31
Posted By: Harish

Start Scroll from Different Position in React Native

Generally, content inside a scrollview starts from x: 0 and y: 0 position. But what if you want to change the content's starting position to different coordinates, like start scrolling from the middle of the content?

In those situations, we can use contentOffset prop which takes x and y values and starts the content from that point. Here, we have to set the coordinates based on the scroll direction.

Lets see this prop in action from the below example.

Create A New Project

Create a new react-native project by using npx. Check documentation for creating a new react native project.

npx react-native@latest init ScrollViewRN

Example Implementation

We will create a scrollview screen with color blocks to see their initial starting position with changed position through contentOffset prop.

Import and add ScrollView from react-native with random color block views to get content for scrolling.

//App.tsx
...
import { View, ScrollView } from 'react-native';
...
<ScrollView
  contentContainerStyle={styles.scrollview_container}
>
  {
    colors
      .map((color: string) => {
        return (
          <View
            key={color}
            style={[
              styles.view,
              {
                backgroundColor: color
              }
            ]}
          >
          </View>
        )
      })
  }
</ScrollView>
...

For styling and colors array, check below complete code block.

If we run the app,

#for Android
npx react-native run-android

#for ios
npx react-native run-ios

We can see that the scroll position starts normally from the starting point of the orange color block.

Start Scroll from Different Position in React Native

But if we change the start position by assigning a point to contentOffset prop, the starting position of the scroll changes to the given offset position.

Here, the coordinates are nothing but the width and height values. Assign width values to x and height values to y coordinate.

...
const [offset, _] = useState<PointProp>({ x: 0, y: 250 });
...
<ScrollView
  ...
  contentOffset={offset}
>
...
</ScrollView>
...

In our example, each color block has a height of 300. So, I assigned a 250 value to y coordinate. If we reload the screen, we can see that the position starts from the end of the orange block.

Start Scroll from Different Position in React Native

As you can see, we changed only the y position without altering x position. This is because of the scrollview direction.

If we have a vertical scrollview, then scrolling happens along the y-axis, so the change is in y coordinate and vice-versa for horizontal scrollview.

Changing both coordinates of contentOffset at the same time will give irregular output. Only change the applied axis coordinate based on the scrollview direction.

Complete code of our example,

//App.tsx
import React, { useState } from "react";
import {
  Text,
  StyleSheet,
  SafeAreaView,
  StatusBar,
  View,
  ScrollView,
  PointProp,
} from "react-native";

const colors = [
  'orange',
  'green',
  'blue',
  'maroon',
  'violet',
  'darkorange',
  'gold',
  'darkgreen',
  'aquamarine',
  'cadetblue'
];

export default function App() {
  const [offset, _] = useState<PointProp>({ x: 0, y: 250 });
  return (
    <SafeAreaView style={{ flex: 1, backgroundColor: 'white' }}>
      <StatusBar
        barStyle="dark-content"
      />
      <View style={styles.container}>
        <Text style={styles.text}>
          ifelsething.com
        </Text>
        <Text style={styles.text}>
          change starting position of scrollview content
        </Text>
        <ScrollView
          contentContainerStyle={styles.scrollview_container}
          contentOffset={offset}
        >
          {
            colors
              .map((color: string) => {
                return (
                  <View
                    key={color}
                    style={[
                      styles.view,
                      {
                        backgroundColor: color
                      }
                    ]}
                  />
                )
              })
          }
        </ScrollView>
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    margin: 10,
    gap: 20
  },
  text: {
    fontSize: 15,
    color: 'black',
    fontStyle: 'italic'
  },
  scrollview_container: {
    gap: 10
  },
  view: {
    flex: 1,
    width: '100%',
    height: 200,
    borderRadius: 10,
    alignSelf: 'center'
  }
});

Share is Caring

Related Posts