ReactNative ScrollView will not scroll to the bottom - react-native

If I try to scroll to the bottom of my ScrollView, it bounces back to its default position and won't let me view the entirety of its content.
My ( truncated ) setup is fairly simple :
<View>
<View>
<ABunchOfStuff />
</View>
<View style={styles.sectionNode} >
<ABunchOfStuff />
</View>
<ScrollView> <------ My broken ScrollView :(
<View>
<ABunchOfStuff />
</View>
</ScrollView>
</View>
This is a simplified version of my actual code. But I'm reaching the conclusion that there's some kind of "unbounded height" going on as in this reference.
I did try making sure everything and all parents have flex: 1 all the way to the child <View> of my <ScrollView> and up to its parents. But that didn't seem to do the trick.
Any idea on how to debug this? I know ReactNative's website recommends this and says it would be easy to do in the inspector ( but with no instructions on how to do it ). If my assumption that there's an "unbounded height" issue, how would one go about and find this rascal unbounded node? Or is it something else?

Try taking flex out of the ScrollView entirely and just put flex: 1 on the parent. That did the trick for me.

For me the problem was setting a paddingVertical, paddingTop or paddingBottom on the ScrollView. Just don't do that. it influences the height of the content of the ScrollView, without the ScrollView adjusting to it appropriately.

The parent view must have style={{flex: 1}} then the scrollview can have style={{flex: 1}} 🥇

The bounded height thingy means the ScrollView itself must be bound.
If the ScrollView has unbounded height, it will stretch with your content and won't scroll.
You can just add height to the ScrollView and see how this works, from there on you can use absolute height or use flex in a way that will limit the ScrollView height to what you want.

This worked for me:
<View style={{flex: 1}}>
<ScrollView>
<View style={{paddingTop: 16, paddingBottom: 16}}>
<SearchBar />
<ItemsContainer />
</View>
</ScrollView>
</View>

You must make sure that ScrollView has fixed height, either by setting it for parents or for itself.
I use flex to set its height instead of specifying it directly so it works on all screen size. So for your code something like
<View style={{flex: 1}}>
<View>
<ABunchOfStuff />
</View>
<View style={styles.sectionNode} >
<ABunchOfStuff />
</View>
<ScrollView style={{flex:0.8}}>
<View>
<ABunchOfStuff />
</View>
</ScrollView>
</View>
More information in react native docs

This works for me
<ScrollView>
<View style={{height:2000}}>
</View>
<ScrollView>
The important thing is to put a defined height for the elements that are inside the ScrollView

<ScrollView style={{flex: 1, marginBottom: 30}} />
items
</ScrollView>

What worked for me was to wrap the ScrollView in View. Then giving the View a height and setting flex : 1 on ScrollView.
Something like this:
<View style={{ height: "60%" }}>
<ScrollView style={{ flex: 1 }}>
<List/>
</ScrollView>
</View>

The suggested answers above with parent flex: 1 and child flex: 1 work, but this thing was causing my bug.
I had <Image> with percentage height and once I replaced the percentage with a number, it fixed the issue.

this will solve your problem
<ScrollView
contentContainerStyle={{flexGrow:1,justifyContent:'space-
between'}}
>
<The Other Components or Lists/>
</ScrollView>

add <Text></Text>
at the bottom inside scrollview. it will give some space

Related

How to get scrollview index

I am using react-native scrollview to slide my imageBackground.
I am using pagingEnabled to swipe the images. But is there a way I could get number of the index when ever I swipe?
I am using the scroll view like the code below. Adding pagingEnabled will make the scrollview work like a swiper but I don't know how to get the index.
<ScrollView horizontal={true} pagingEnabled={true}>
{this.createScrollImageSources(this.state.image)}
</ScrollView>
You could make use of the onScroll method together with the Dimensions module to calculate the currentScreenIndex.
Example:
render
<View style={styles.container}>
<ScrollView pagingEnabled horizontal style={{flex: 1}} onScroll={(e)=>this.handleOnScroll(e)} scrollEventThrottle={5}>
<View style={{width: SCREEN_WIDTH, backgroundColor: 'yellow'}} />
<View style={{width: SCREEN_WIDTH, backgroundColor: 'red'}} />
<View style={{width: SCREEN_WIDTH, backgroundColor: 'green'}} />
</ScrollView>
</View>
handleOnScroll
handleOnScroll(event){
//calculate screenIndex by contentOffset and screen width
console.log('currentScreenIndex', parseInt(event.nativeEvent.contentOffset.x/Dimensions.get('window').width));
}
Working Demo
https://snack.expo.io/HyxzFr2HxU
What I did was to use the onScroll prop to check the current offset of the horizontal scrollview. Then compare the current offset with your device width.
Try:
<ScrollView onScroll={this.handleScroll} />
And then:
handleScroll: function(event: Object) {
console.log(event.nativeEvent.contentOffset.x);
},

How to fixed a <Text> in a scrollView?

My all screen has a scrollView, and there's a in the middle of it. I want when someone scroll up, the text be fixed at the top and does not disappear. How can I do that? I didn't find it anywhere, thanks.
<View style={styles.container}>
<Text style={{ position : 'absolute', textAlign: 'center'}}>
Special Text
</Text>
<ScrollView>
</ScrollView>
</View>
you can do something like this
Use css property position: sticky. that will fixed your text at the top it's called sticky position. So, Please read it https://www.w3schools.com/css/tryit.asp?filename=trycss_position_sticky
Be patient.
Cheer you!
i was trying to implement something similar and i got it done but unfortunately it is kinda complex (relatively) at least compared to what you would do on the web. it requires using the onLayout prop.
state = {zIndex: 0};
<View>
<View style={[your_style, {position: "relative", zIndex: this.state.zIndex}]} onLayout={({nativeEvent}) => {this.outTextHeight = nativeEvent.layout.height}}>
<Text>Special Text</Text>
</View>
<View style={{[your_style, {zIndex: 1}]}>
<ScrollView onScroll={({nativeEvent}) => {if(nativeEvent.contentOffset.y >= (this.insideTextHeight + this.insideTextOffsety){this.setState({zIndex: 2})})}}>
// your content
<View onLayout={({nativeEvent}) => {this.insideTextHeight = nativeEvent.layout.height; this.insideTextOffsety = nativeEvent.layout.y}}>// this maybe the same height so may be unnecessary
<Text>Special Text</Text>
</View>
</ScrollView>
</View>
</View>

React Native avoid {width: '100%'} by default

My code is pretty simple: (relevant parts shown only)
<ScrollView style={{/* padding, centering... */}>
<Text>SHARE WITH YOU FRIENDS</Text>
</ScrollView>
Yet, when I inspect the Text node, its width is 100% of its container, and the grey background goes all the width.
Is there a layout setting to make this Text's width as small as possible? I.e. only until the end of the Text.
You can use alignSelf property:
<View style={{alignSelf: 'flex-start'}}>
<Text>SHARE WITH YOU FRIENDS</Text>
</View>
For Scroll view you can try like
<ScrollView contentContainerStyle={{ alignItems: 'flex-start'}}>
<Text >SHARE WITH YOU FRIENDS</Text>
</ScrollView>
Hope this will help!

how to make color cover the background color?

I tried rgba(156, 39, 176, 1) but it does not cover the color under it.
How can I make the purple color circle cover the part of background bell?
First try setting zIndex on the badge to make it render on top. However Android has some zIndex issues, so if that doesn't work then you have to render it after. So you have this right now:
<View>
<Badge>
<Image>
</View>
You need to do:
<View>
<Image>
<Badge>
</View>
You can use react-native-icon-badge to create this notification icon symbol with count.
<View style={styles.container}>
<IconBadge
MainElement={
<View>
<Image
style={{width:60,height:60,margin:3}}
source={bell}
/>
</View>
}
BadgeElement={
<Text style={{color:'#FFFFFF'}}>3</Text>
}
IconBadgeStyle={
{width:30,
height:30,
backgroundColor: '#9c27b0'}
}
Hidden={this.state.BadgeCount==0}
/>
</View>

Element with absolute position is cut off by other component

I have a toolbar in my RN app. That toolbar has a button that is oversized on purpose and is overflowing from the component.
The oversized button is covered by an other component in the same page.
touchable:{
backgroundColor:'#3d3d3d',
borderRadius:27.5,
position:'absolute',
left:width/2 -25,
bottom:10,
alignItems:'center',
borderColor:'black',
width:55,
height:55,
justifyContent:'center',
}
Mark up:
render() {
return (
<View style={{flex: 1}}>
<View style={{position:'absolute', width:42,height:42,left:20,top:(height-42)/3,zIndex:3}}>
<Image style={{}} source={require('./Images/Ellipse 36.png')} />
<Image style={{position:'absolute',top:14,left:14}} source={require('./Images/Asset 65.png')} />
</View>
<View style={{position:'absolute', width:42,height:42,right:20,top:(height-42)/3,zIndex:3}}>
<Image style={{}} source={require('./Images/Ellipse 36.png')} />
<Image style={{position:'absolute',top:10,left:12}} source={require('./Images/Asset 66.png')} />
</View>
<View><TopToolbar text='Swipe' navigator={this.props.navigator} user={this.props.user}/></View>
<ScrollView style={{zIndex:1,}}><Inders style={{flex: 1}} navigator={this.props.navigator} credentials={this.props.credentials}/></ScrollView>
<View style={{zIndex:0,}}><BottomToolbar user={this.props.user} navigator={this.props.navigator} credentials={this.props.credentials}/></View>
</View>
)
}
Where Inders is a component.
I tried changing the order of the components but it didn't work.
What is the way to make a button "float" from another component?
Open inspector in the Dev tools menu and find out who cut your component, I also like to set backgroundColor to see their position, it make solve this type of bugs mack more easy.
The solution is to wrap the toolbar in another View, so that the new View is the parent of the element that you want to "float".