Get ScrollView Content Size in React Native
Published On: 2024-06-21
Posted By: Harish

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
}
});