agmcleod
agmcleod

Reputation: 13621

React native, children of ScrollView wont fill full height

So I have a horizontal scrollview at the top of the view. The ScrollView contains nodes that have a specified width. I then have a border on the bottom of the ScrollView, like you can see in this screen cap: https://i.sstatic.net/zcvDj.png

As you can see the child nodes of the ScrollView at the top don't reach the border. However, if I change the ScrollView to a View with flexDirection: 'row', then the child nodes fill the height fine. I've tried changing a few properties on the scrollview, such as:

None of those seem to fix the issue.

The scrollview code & style:

var styles = StyleSheet.create({
  nav: {
    padding: 0,
    marginTop: 30,
    flex: 1,
    borderBottomWidth: 1,
    borderColor: '#000000'
  }
});

<ScrollView
  style={[{width: screen.width}, styles.nav]}
  horizontal={true}
  showsHorizontalScrollIndicator={true}
  automaticallyAdjustContentInsets={false}>
  {dayNavItems}
</ScrollView>

The child components (makes up dayNavItems)

const styles = StyleSheet.create({
  container: {
    paddingLeft: 15,
    paddingRight: 15,
    width: 50,
    justifyContent: 'center'
  },
  odd: {
    backgroundColor: '#ccc'
  },
  selected: {
    backgroundColor: '#39b54a'
  },
  text: {
    fontFamily: 'Optima'
  }
});

class DayNavItem extends React.Component {
  static propTypes = {
    day: React.PropTypes.object.isRequired,
    odd: React.PropTypes.bool,
    selectDay: React.PropTypes.func.isRequired,
    selected: React.PropTypes.bool
  };

  render() {
    const d = new Date(this.props.day.created_at);
    const viewStyles = [styles.container];
    if (this.props.selected) {
      viewStyles.push(styles.selected);
    } else if (this.props.odd) {
      viewStyles.push(styles.odd);
    }
    return (
      <TouchableOpacity style={viewStyles} onPress={() => this.props.selectDay(this.props.day.uuid)}>
        <View>
          <Text style={styles.text}>{getMonth(d)}</Text>
          <Text style={styles.text}>{d.getDate()}</Text>
        </View>
      </TouchableOpacity>
    );
  }
}

Upvotes: 94

Views: 68667

Answers (8)

Mahendra Liya
Mahendra Liya

Reputation: 13218

I had a ScrollView inside SafeAreaView. Since the options shared above didn't work for me, sharing my fix for the reported issue:

<SafeAreaView style={{flex: 1}}>
  <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'}/>
  <ScrollView contentContainerStyle={{flexGrow: 1}} bounces={false}>
  <View style={{flex: 1}}>
    <Tab.Navigator screenOptions={{ headerShown: false }}>
        <Tab.Screen name="HomeStack" component={HomeStackScreen} />
        <Tab.Screen name="SettingsStack" component={SettingsStackScreen} />
    </Tab.Navigator>
  </View>
  </ScrollView>
</SafeAreaView>

I had to apply {{flex: 1}} style to SafeAreaView and the child of Scroll and set contentContainerStyle={{flexGrow: 1}} for ScrollView

Upvotes: 0

Albert Vila Calvo
Albert Vila Calvo

Reputation: 15835

I always end up creating this component in all my projects:

import * as React from 'react'
import { ScrollView, ScrollViewProps, StyleSheet } from 'react-native'

export function FullHeightScrollView(
  props: {
    children: React.ReactNode
  } & Omit<ScrollViewProps, 'contentContainerStyle'>
) {
  return (
    <ScrollView contentContainerStyle={styles.grow} {...props}>
      {props.children}
    </ScrollView>
  )
}

const styles = StyleSheet.create({
  grow: { flexGrow: 1 },
})

Use it in place of React Native's ScrollView.

Upvotes: 5

Henrique Bruno
Henrique Bruno

Reputation: 725

I have made a simple package for those who just want, like me, a working out of the box ScrollView, without having to apply all the time the styles to make it work properly.

https://github.com/SrBrahma/pagescrollview

Usage:

import { PageScrollView } from 'pagescrollview';

<PageScrollView>
  {/** Your contents */}
</PageScrollView>

Upvotes: -2

Elvis S.
Elvis S.

Reputation: 462

If ScrollView is wrapped inside of a SafeAreaView, put flex: 1 on SafeAreaView, this did the trick for me after hours of debugging...

Parent:

enter image description here

Child (styles ScrollView I implemented has nothing to do with the current issue you reported):

enter image description here

Upvotes: 4

Raphael Karanja
Raphael Karanja

Reputation: 3074

Adding contentContainerStyle={{flexGrow: 1}} will do the trick.

<ScrollView contentContainerStyle={{flexGrow: 1}}>

</ScrollView>

Upvotes: 289

Malte Schulze-Boeing
Malte Schulze-Boeing

Reputation: 1145

There is a property called contentContainerStyle for ScrollView. I just solved a similar issue where I set flex: 1 to the ScrollView's styles, ScrollView's contentContainerStyle, and the child View component.

Upvotes: 18

Fellow Stranger
Fellow Stranger

Reputation: 34023

The other answers are correct, but just to provide a clarifying example:

<ScrollView contentContainerStyle={{ flex: 1 }}>
  {children}
</ScrollView>

Upvotes: 10

Stano
Stano

Reputation: 171

Setting flex: 1 for ScrollView's contentContainerStyle property did the trick for me.

Upvotes: 6

Related Questions