ScrollView minHeight to take up all the space
Asked Answered
P

6

17

I have a ScrollView which content doesn't necessarily exceeds it's size. Let's say it's a form where, upon errors, it expands to add error messages and then it exceeds the ScrollView size and thus is why I'm using that scroll.

The thing is that I want the content to always be at least of the same size of the ScrollView. I'm aware of the minHeight property, but the only way I found to use it is re-rendering, which I'd like to avoid.

I'm using redux for state management and this is what I have

<ScrollView
  contentContainerStyle={[ownStyles.container, {minHeight: this.props.scrollHeight}]}
  style={this.props.style}
  showsVerticalScrollIndicator={false}
  onLayout={(event) => {
    scrollHeight = event.nativeEvent.layout.height;
    this.props.setScrollContentHeight(scrollHeight);
  }}
>

Where the this.props.setScrollContentHeight triggers an action which enters the height on the state, and this.props.scrollHeight is said height. So that after the first render where the onLayout function is triggered, the state is updated with the ScrollView's height, which I then assign as minHeight to its content.

If I set the content's style to flex: 1 then the ScrollView won't scroll.

Can you think of a way to avoid that second render for performance purposes?

Thank you!

Pepsinate answered 12/8, 2016 at 15:40 Comment(2)
and using height: 100%; doesn't do the job?Brandiebrandise
refer this: github.com/facebook/react-native/issues/3422Cade
T
25

You should use flexGrow: 1 for the ScrollView and flex: 1 inside the ScrollView, to get a ScrollAble but at least as big as possible <View>.

There has been a discussion about it in react-native and tushar-singh had the great idea to it.

Thearchy answered 22/12, 2017 at 10:31 Comment(2)
Be careful that for ScrollView you cannot use style directly but contentContainerStyle: <ScrollView contentContainerStyle={{flexGrow: 1}}>Evenings
Also, if your inner view is a KeyboardAvoidingView like mine was, you'll need to use <KeyboardAvoidingView contentContainerStyle={{flex: 1}} style={{flex: 1}}> (or, at least I did).Tound
I
17

It has been a long time but I struggled with the same issue. The easy way to do it is to use flexGrow: 1 instead of flex:1 on both scrollView's style and contentContainerStyle props. The content will take at least 100% of space and more if needed.

Indole answered 1/8, 2018 at 13:7 Comment(1)
THX! However contentContainerStyle was enough for meSilk
P
14

A couple of solutions of doing this are:

  • Use a minHeight on the ScrollView (but this requires taking into account the screen dimension to render correctly)
  • Use a flexGrow: 1 on the ScrollView contentContainerStyle and a flex: 1 to the inner content:
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
  <View style={{ flex: 1 }}>
    ...
  </View>
</ScrollView>
Pomelo answered 16/7, 2019 at 11:36 Comment(1)
This is right answer. Remember, you shouldn't wrap it in the another <View> block without Flex Grow: 1, because you will get a white space in the bottom on the screen.Juanajuanita
P
7

i want to share my solution, for me nothing of https://github.com/facebook/react-native/issues/4099 worked. Also i cannot comment there because facebook blocked the thread ¬.¬ !

Basically my solution is set flexGrow: 1 in contentContainerStyle on the ScrollView component, and wrap all the content inside in a View component with a height property setted with the screen size. Here the example code:

import { Dimensions } from "react-native";

let screenHeight = Dimensions.get('window').height;

<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
   <View style={{height: screenHeight}}>
    ... your content here ...
   </View>
</ScrollView>

Polydipsia answered 31/7, 2019 at 4:21 Comment(0)
T
1

I know this is a little late, but I think wrapping the contents inside of that ScrollView with a View with minHeight style property will do the trick.

Trembly answered 17/11, 2016 at 3:47 Comment(0)
W
-2
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
  <View style={{ flexGrow: 1 }}>
    Your content
  </View>
</ScrollView>

That worked for me.

Wilkes answered 25/5, 2020 at 3:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.