ifelsething logoifelsething

Get ScrollView Content Size in React Native

Published On: 2024-06-21
Posted By: Harish

Get ScrollView Content Size in React Native

We can calculate the size of the scrollview by using onLayout callback to measure the size of any react native view. But with this callback, we can only get the size of the scrollview not the scrollable content size.

So, to get the content's size, we can use onContentSizeChange callback which returns only the content's width and height. This callback returns an event whenever the scrollable content's width or height changes.

Let's check its output.

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 with color blocks to check the size of the scrollview and its content.

Import and add ScrollView with some color blocks.

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

If we run the app,

#for Android
npx react-native run-android

#for ios
npx react-native run-ios

We will see some scrollable color blocks.

Now add onLayout and onContentSizeChange callbacks to the scrollview and console log them.

...
<ScrollView
  ...
  onLayout={(e: LayoutChangeEvent) => console.log("ScrollView Layout: ", e.nativeEvent)}
  onContentSizeChange={(width: number, height: number) => console.log(`Width: ${width}, Height: ${height}`)}
>
...
</ScrollView>
...

If we re-run the metro builder, we can see the logs of both scrollview and its content sizes.

LOG  Width: 355, Height: 2090
LOG  ScrollView Layout:  {"layout": {"height": 551, "width": 355, "x": 0, "y": 76}, "target": 175}

You will get the first log which includes the height of the statusbar (if any). So ignore that.

By checking the logs, we can see that the height of the scrollview is less than its content height. In this way we can get the size of the content.

Whenever the scrollable content size changes, onContentSizeChange callback returns an event.

Complete code of our example,

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

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

export default function App() {
  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}>
         scrollview content size
        </Text>
        <ScrollView
          onLayout={(e: LayoutChangeEvent) => console.log("ScrollView Layout: ", e.nativeEvent)}
          onContentSizeChange={(width: number, height: number) => console.log(`Width: ${width}, Height: ${height}`)}
          style={{ flex: 1 }}
          contentContainerStyle={styles.content_container}
        >
          {
            colors
              .map((color: string) => {
                return (
                  <View
                    key={color}
                    style={[
                      styles.view,
                      {
                        backgroundColor: colors }
                    ]}
                  >
                  </View>
                )
              })
          }

        </ScrollView>
      </View>
    </SafeAreaView>
  );
}

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

Share is Caring

Related Posts