react-nativereact-native-flatlistreact-native-scrollviewreact-native-flexbox

ScrollView children height relative to container


I'm looking to create a react-native scrollable feed of views whose heights are 80% of the container. My code currently looks like

const FeedItem = () => (
  <View style={styles.feedItem}>
    <Text>Hello</Text>
  </View>
);

const Feed = () => (
  <ScrollView style={styles.feed} contentContainerStyle={styles.feedContentContainer}>
    <FeedItem />
    <FeedItem />
    <FeedItem />
  </ScrollView>
);

const App = () => (
  <View style={styles.app}>
    <Feed />
  </View>
);

const styles = StyleSheet.create({
  app: {
    flex: 1,
  },
  feed: {
    height: '100%',
  },
  feedContentContainer: {
    height: '80%',
  },
  feedItem: {
    height: '100%',
  },
});

However, this causes the scroll view to no longer scroll. According to what I've read this has something to do with flex and I've tried so many approaches to this for 2 days straight to no avail. Does anyone know the proper approach to setting heights without messing up the scrolling in the view?

I'm also experiencing the same problem in FlatList so hopefully the answer for ScrollView also applies to FlatList. Thanks!


Solution

  • As the ScrollView does not have its own height and it depends upon its children for the Height. It's better to set the height for a child node.

    For example if you're setting a height of 80% for a child item out of full device height.

    We could do this like

    import { useSafeArea } from 'react-native-safe-area-context';
    import { Dimensions } from "react-native";
    const insets = useSafeArea();
    const { height } = Dimensions.get("window");
    

    And in your JS

    height: ((height - insets.top - insets.bottom) * 80(your percentage))/ 100
    

    You set this height to the children elements.

    Note: I'm using this external library for insets.