Currently, the only way I can implement a working ScrollView is if it's nested within a view of bounded height or {flex: 1}. The docs make it sound as if only the height of the ScrollView itself needs to be set in order to function.
I could be implementing it wrong but rendering a plain ScrollView with a set height that's not nested produces a ScrollView that bounces but does not scroll.
Experiencing the same thing. This sure seems like a bug to me, but if it's not the docs should definitely reflect that you need to nest it in another View and can't set height on the ScrollView directly.
Check this out to see it happen: https://rnplay.org/apps/pTCbwA
After you see the full screen ScrollView, just wrap the ScrollView in an unstyled view to see it display at the correct height.
wasted too much time trying to figure it out :/
:+1: needs fix or doc update
Neither my profile component or the dashboard component is scrolling. Even when i cut and paste the code from Branch 13 in this egghead.io tutorial Repo i still cant get scrolling. https://github.com/eggheadio/react-native-gh-notetaker/blob/13-finish-repositories-component/App/Components/Profile.js
This is the component code which works for rendering the data but does not scroll the data. Anything stand out here?
var React = require('react-native');
var Badge = require('./Badge');
var Separator = require('./Helpers/Separator');
var {
Text,
View,
ListView,
StyleSheet,
ScrollView
} = React;
var styles = StyleSheet.create({
container: {
flex: 1
},
buttonText: {
fontSize: 18,
color: 'white',
alignSelf: 'center'
},
rowContainer: {
padding: 10
},
rowTitle: {
color: '#48BBEC',
fontSize: 16
},
rowContent: {
fontSize: 19
}
});
class Profile extends React.Component{
getRowTitle(user, item){
item = (item === 'public_repos') ? item.replace('_', ' ') : item;
return item[0] ? item[0].toUpperCase() + item.slice(1) : item;
}
render(){
var userInfo = this.props.userInfo;
var topicArr = ['company', 'location', 'followers', 'following', 'email', 'bio', 'public_repos'];
var list = topicArr.map((item, index) => {
if(!userInfo[item]){
return <View key={index}/>
} else {
return (
<View key={index}>
<View style={styles.rowContainer}>
<Text style={styles.rowTitle}> {this.getRowTitle(userInfo, item)} </Text>
<Text style={styles.rowContent}> {userInfo[item]} </Text>
</View>
<Separator />
</View>
)
}
});
return (
<ScrollView style={styles.container}>
<Badge userInfo={this.props.userInfo}/>
{list}
</ScrollView>
)
}
};
Profile.propTypes = {
userInfo: React.PropTypes.object.isRequired
}
module.exports = Profile;
https://jsfiddle.net/lokal/v7zdb16g/
Thank you.
Exactely the same problem...
How to set the ScrollView to "take all the remaining space" instead of setting height: XX ?
Depending on the device which is being used, the remaining height varies a lot...
How is this not trivial? I only get a working scrollView with fixed height so far (no specific scrollview wrapper needed), setting flex:1 on contentContainerStyle, style or wrapper style, setting it on any or all of them does not work for me. It just renders the entire view, overflowing the screen, no scroll.
edit: check all flex values on the page. In my case, there was another flex element above the scroll view that made things weird.
I also have this issue...
+1, btw, your views root container should contain flex: 1, to avoid the inner scrollview container to overflow off the screen
Use contentContainerStyle={{flex:1}} on ScrollView tag, that should fix your problem.
style={{ flex: 1}} isn't working for me. The content in our ScrollView is loaded in dynamically from an API call. The component that holds that dynamic content is resizing correctly, but it's as though the parent isn't taking that height change into account and I can't scroll to the bottom of our list. Do I need to do something with onLayout to notify that parent ScrollView of the height change?
@gkrinc how are you setting the inner state of the scrollview once you receive your API call data? you can try triggering a re-render via this.setState({...})
or using this.forceUpdate()
.
Thanks @ospfranco I got it working. I ended up with a static height on something that was causing the issue. Totally my fault :s
I ended up solving this problem by wrapping the ScrollView in a View with {flex:1} and setting nothing about height in my ScrollView style nor contentContainerStyle.
Takes the full height and goes deep down the screen.
But with this solution you cannot really rely on "flex" in direct children. If the screen isn't initially filled with content you'll have some unused spaces.
I tried to set up a bounded height scrollview, but it seems like to automatically take up all remaining height of parent, the only way to do it for me is to use a wrapper view outside of scrollview
For me contentContainerStyle={{flex: 0}}
did the trick.
@alexindigo Makes sense because the size of the contentContainer should not flex, it should match the size of the contents.
{flex: 1}
works in 0.43. or
{flexGrow: 1,flexShrink: 1, flexBasis: 1,}
I also experience the same thing. Except that scrolling to bottom would not be actual bottom, I would have content cut off. Unless I wrap it with <View>
and set flex:1
. Setting flexGrow:1
on the view did not fix it for me. I would get this content cut off bug when adding a marginVertical
to the ScrollView or FlastList too.
In my case also the scrollview doesnot scrolls inside a view conmponent.
Any solutions for it?
Just ran into this. I wanted a horizontal ScrollView
to take as little height as possible. The ScrollView
by itself displayed as if it had flex: 1
specified, which it didn't. Thanks to @bistacos, wrapping it in a View
solves my problem.
none of the solutions above worked for me, perhaps because we all tested these solutions on different versions of RN... I'm on RN47, and the only solution that worked for me, was manually measuring out the 3 different heights i needed, and then dynamically swapping between heights based on what content needed the extra height. So in the end it, this is what finally worked for me:
contentContainerStyle={{
height: userType === 'SHOPPER' ? 600 : userType === 'DIST' && !DistributorId ? 660 : DistributorId ? 860 : 700
}}
I had the same issue as @mariotacke response above.
Do you understand why we would have to wrap this in a View? Works for me, but I still don't understand why setting the contentContainerStyle or style to flex: 0 wouldn't work. I guess because there is another container that is automatically set to 1 internally?
I am on RN 0.47 and none of the options you guys provided worked for me. I tried setting static height on the ScrollView itself, around, within and still nothing. It bounces to the top.
RN 0.48.2: When trying to create a horizontal scrollview that takes the minimal vertical space possible, the solution was to set flexGrow:0 on the ScrollView. Setting flex:0 on it did not have any effect for reasons unknown.
rn 0.45.1:It seems that only the first Scrollview will appear this phenomenon, and adding an extra empty Scrollview can solve the problem。
@dushaobindoudou trick helped me solve the issue
"react-native": "^0.48.4",
flex:1 working but not scrolling,
flexGrow:1 working and scrolling,
flexShrink:1 working but not scrolling,
flexBasis:1 not working
i think it should be like this.
<ScrollView contentContainerStyle={{flexGrow:1}}>
<View style={{flex:1}}><View>
</ScrollView>
this is working in my project.
Mine works with exactly as shown by @mtnst. Here is my scrolling view component:
import React from 'react'
import { StyleSheet, ScrollView } from 'react-native'
import * as Animatable from 'react-native-animatable'
const E1ScrollView = ({ children, animation, bottomBorder, style }) => {
const { container, E1bottomBorder } = styles
return (
<ScrollView
contentContainerStyle={{ flexGrow: 1 }}
scrollEnabled>
<Animatable.View
style={[container, (bottomBorder) ? E1bottomBorder : null, style]}
animation={animation}
iterationCount={1}>
{children}
</Animatable.View>
</ScrollView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F0F0F0',
flexDirection: 'column'
},
E1bottomBorder: {
borderBottomWidth: 5,
borderColor: '#DD0426',
}
})
export { E1ScrollView }
If you would like to sample it, simply import that "common" component in to whatever screen you plan to use it and do this:
import { E1ScrollView } from '../common'
// ...
// Notice how you can overwrite styles by adding style={{ backgroundColor: 'red' }} to <E1ScrollView />
return (
<E1ScrollView animation="fadeIn" bottomBorder>
<View style={{ flex: 0 }}><Text>test</Text></View>
<View style={{ flex: 0, flexDirection: 'column' }}>
<Text>test</Text>
<Text>test</Text>
<Text>test</Text>
</View>
<View style={{ flex: 1 }} />
<View style={{ flex: 0 }}><Text>test</Text></View>
</E1ScrollView>
)
The part I would like to make sure you're aware of is you can create <CardSection />
View elements that have either flex: 0
or flex: 1
style and you will get effortless stacking. Then, you just need to work with margins and padding.
The <View style={{ flex: 1 }} />
element as I demonstrated above is a critical design element to be aware of, in my opinion. I found it somewhere along my journeys and it makes filling areas pretty effortless.
If your screen receives props that add DOM elements, your view will respond in an expected manner.
@mariotacke you could just apply flexGrow: 0 to your ScrollView
None of these tricks worked for me. I ended up just adding the style paddingBottom: 600
to the ScrollView to force it to fill the screen.
@teckel12 my responce was for the opposite problem. In the current version of react native ScrollView has flexGrow: 1 as default and fills all space (for some reason, View hasn't that).
In your case you should only ensure that all your ScrollView`s containers have flex: 1.
I could help you more if you provide your layout example.
If I set the style of ScrollView to flex: 1
it doesn't render anything at all. It's like it's one pixel high.
It seems that the trick is to making EVERY parent View to have a style of flex: 1
, not just the first parent View. When doing that, ScrollView doesn't need the flex: 1
either.
@teckel12 sure. As I said.
This mix work for me:
1 View Global with "flex: 1",
1 View for ScrollView with "flex: 1",
1 ScrollView with "contentContainerStyle={{flexGrow:1}"
render() {
return (
// Global View
<View style={{flex: 1}}>
{/* View for ScrollView */}
<View style={{flex: 1}}>
<ScrollView contentContainerStyle={{flexGrow:1}}>
<View style={{flex: 1, alignItems: 'center' }}>
{/* More things */}
</View>
</ScrollView>
</View>
{/* Another Component */}
</View>
);
}
@zicrox I also needed to use <ScrollView contentContainerStyle={{ flexGrow: 1 }}>
along with all parent containers using style={{flex: 1}}
. I needed to use React Developer Tools to diagnose and get this resolved.
@teckel12 think it is run well with all parent containers using style={{flex: 1}}
as long asScrollView
is inside of a parent with<View style={{flex: 1}}>
🤔
In version 0.50.3, I experience a problem with ScrollView where it doesn't let me scroll to the last few items. Like I have 45 records on the list and on reaching 41 I can see the list bouncing but not showing the rest. When it bounces I can see the rest of the records rendered. Tried using ScrollView, ListView, and FlatList none of them worked.
@venk-aw
I also have the same problem but only if I set height in child components using percentage value.
@nikolal can confirm, also other dynamic height attributes such as minHeight
. Trying to find out what causes this, looks like a precision error.
I spent the last couple of hours trying all the solutions in this thread with no success. Here is what worked for me (v.0.50.3)
.
Each View preceding ScrollView
has to have flex:1
, all the way to the root component.
As an example, I have my root view ProgramsContainer
like so:
Class ProgramsContainer extends Component {
render() {
return (
<ProgramsChild />
);
}
class ProgramsChild extends Component {
render() {
return (
<View Style={{flex:1}}>
<ProgramsList />
</View>
)
}
class ProgramsList extends Component {
render() {
return (
<ScrollView>
{this.renderList()}
</ScrollView>
)
}
}
This is a simple example, in my case, ProgramsList
was nested 4-5 levels down from ProgramsContainer
, and I had to add flex:1
to every View
wrapper.
Note that there are no styles applied to ScollView
.
Has anyone tried to make a scrollable map marker's callout? I think the issue with map is that the map is scrollable, probably has to disable map's scroll while scrolling the callout?
Edit: callout is supposed to be only text and thus not scrollable.
I ran into the same issue of my ScrollView not scrolling over the full height of its children. I found that the issue was that some of the child components had set heights.
By changing these set heights to top and bottom margin/padding, the ScrollView was able to capture the correct scrollable boundaries.
Same issue is also happening when using a FlatList. I've tried the same example and styling with ListView and it correctly fills in the height and evenly seperates touchable opacity compoanents.
Not sure all the issues here are related, but for my usecase I wanted to bound ScrollView with maxHeight. You have to set flexGrow: 0
on the scrollview directly (not the container) to do so, see https://stackoverflow.com/questions/48811028/can-a-scrollview-be-bounded-by-maxheight/48811243#48811243
Previously, i only try to add flex:1 to the parent of ScrollView => not work
Later, I try to find all the parent to the root component (like app component) and add flex:1 to each parent component. => work perfectly
I'm triaging older issues and it seems like this thread has turned into a discussion of various workarounds. If you'd like to change the docs in any way, we do have a new repo where contributions are more than welcome: https://github.com/facebook/react-native-website
For individual issues that you believe need addressing in the component itself, may I ask that you open a new issue? That would be more actionable for people interested in contributing.
Hopefully, the discussion here has been useful for people, and if you believe some of the content is worth sharing more broadly, you now know how to contribute to the docs. Thank you!
@teckel12
this is main concept . thanks working fine ...
But not working in android device . ios working fine
const {width, height} = Dimensions.get('window');
const metrics = {
screenWidth: width < height ? width : height,
screenHeight: width < height ? height : width,
};
<ScrollView style={{flex: 1}} contentContainerStyle={{height: metrics.screenHeight + StatusBar.currentHeight}}>...</ScrollView>
Added style={{ flex: 1 }}
to the parent component of ScrollView works for me.
The height of ScrollView
of mine is height:'100%'
This is what worked for me. Here's the Working Example for your trying needs :)
render() {
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<Text>HEADER</Text>
</View>
<View style={{ flex: 6 }}> // Change this to affect ScrollView size
<ScrollView contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }}>
<FlatList
data={listItems}
renderItem={Item}
keyExtractor={(index, item) => item}
style={{ flexGrow: 0 }} // This was the solution to centering
/>
</ScrollView>
</View>
<View style={{ flex: 1 }}>
<Text>FOOTER</Text>
</View>
</View>
);
}
Also you can read the whole detail in this SO thread.
@fpenovi I don't know what you try to do but nesting a FlatList inside a ScrollView isn't a very good idea IMHO, and actually lead to some weird behaviors in my experience (like onEndReached
firing continuously...)
It's interesting that I fixed this issue but I really don't know how
I needed the scrollview to take all the height regardless of the content. For me,
{height:'100%',
alignSelf:'stretch'}
did the trick.
I implemented scrolling on fullscreen by adding the following prop on ScrollView Component.
contentContainerStyle={{ alignItems: 'center', flexGrow: 1 }}
style={{ flex: 1}} isn't working for me. The content in our ScrollView is loaded in dynamically from an API call. The component that holds that dynamic content is resizing correctly, but it's as though the parent isn't taking that height change into account and I can't scroll to the bottom of our list. Do I need to do something with onLayout to notify that parent ScrollView of the height change?
for everyone who has this problem - two way of fixing it. First is to calculate your content height and set height: XXX of scroll view dynamically
Second options is to use native-base library. Its using
I'm using RNv0.57
and I have the same issue, the ScrollView
fill all empty space of wrapper even in horizontal mode. At the first, I wrapped the ScrollView
with a View
element and everything became awesome, the ScrollView
height became as short as possible. but with a flexGrow: 0
style to ScrollView
I got the true result without any wrapper.
...
<ScrollView style={styles.scrollView}>
...
const styles = StyleSheet.create({
scrollView: {
flexGrow: 0
},
...
});
TL;DR: Just with a flexGrow: 0
style make your ScrollView
height as short as possible.
I had the same issue, what worked for me was setting ScrollView contentContainerStyle to flex: 0
and the outside View of that to flex: 1
In my case, I put all the way up to top parent <View style={{flex:1}}>
... till the child <ScrollView style={{flex:1}}>
fixed the issue.
Magic lies in flex-grow
!
still having the same issues! My scrollview doesnt show everything! I've tried almost everything here and nothing works! Still cut off! :/
My problem was that I wanted some padding on all sides of the ScrollView. On iOS this was handled as I was expecting, but caused the content to be cutoff on Android. What fixed it for me was to nest all scrolling content within another view with a margin.
<ScrollView>
<View style={{ margin: 32 }}>
...content...
</View>
</ScrollView>
Nothing worked here for me, so I just added a marginBottom
to my last element. Not clean, but works.
Create a new view in Scrollview and give it flext:1
version: react native: 0.59.8
Having this issue, my children are dynamic so if I have enough it will fill the screen but if I don't it cuts off. such a pain
Most helpful comment
Use contentContainerStyle={{flex:1}} on ScrollView tag, that should fix your problem.