ScrollView not respecting flex rules - react-native

This results in a screen that is half blue and half yellow, should it not be 2/3 yellow?
<View style={{flex:1,flexDirection:'column'}}>
<View style={{flex:1,backgroundColor: 'blue'}}></View>
<ScrollView style={{flex:2}} contentContainerStyle={{flex:1,backgroundColor: 'yellow'}}></ScrollView>
</View>

In general you are right, but react native's ScrollView behaves a little bit differently. As you can read in the docs:
Keep in mind that ScrollViews must have a bounded height in order to
work, since they contain unbounded-height children into a bounded
container (via a scroll interaction). In order to bound the height of
a ScrollView, either set the height of the view directly (discouraged)
or make sure all parent views have bounded height. Forgetting to
transfer {flex: 1} down the view stack can lead to errors here, which
the element inspector makes easy to debug.
In order to achieve your wanted behavior, you can do the following:
<View style={{flex:1,flexDirection:'column'}}>
<View style={{flex:1,backgroundColor: 'blue'}}></View>
<View style={{flex:2}}> // surround scrollview with flex 2
<ScrollView contentContainerStyle={{flex:1,backgroundColor: 'yellow'}}></ScrollView>
</View>
</View>

Related

How do I make an absolut positioned touchable element on top of a FlatList catch only press events and let other events propagate to the FlatList?

I have a FlatList in React Native with fullscreen image and video items (with pagingEnabled). I want to have a short descriptive touchable text floating on top of the FlatList, to open up a view with some information about the image/video when pressed.
To make the user experience nice, I'd like to be able to scroll the FlatList through the touchable text as well. I.e. if the user happen to start their scrolling motion on top of the text, the FlatList would scroll but if it is a simple press event I'd like to open the view with details about the image/video.
No mater what I try I end up with either the text being able to react to the press OR the FlatList being able to scroll. I have tried different configurations with a custom PanResponder and pointerEvents but seem to always end up with a state were one thing does not work. Do you guys have any smart ideas? I am probably just stuck in the wrong train of thought.
This is a simplified view of my component structure:
<View>
<View style={{ position: 'absolute', bottom: 100, zIndex: 10 }}>
<TouchableOpacity onPress={() => console.log('press')}>
<Text>Some Descriptive Text</Text>
</TouchableOpacity>
</View>
<FlatList pagingEnabled horizontal {...otherFlatListProps} />
</View>

ScrollView won't Scroll at all

I have a React page that needs a Scrollview, there's no way around it. The content goes off the bottom of the screen, and it is encapsulated in the ScrollView. I have a red border on the ScrollView element so I can see that it goes past the bottom of the screen where the rest of my content it. However, it just does not want to scroll. I even put an 'onScroll' prop inside with console.log('hit') at one point to see if the ScrollView was even registering my attempts, it was not. This is happening in a couple of similar components, their structure is very similar. The smallest of them looks like this...
<ScrollView style={{borderColor: 'red', borderWidth: 3}}>
<View style={QualityStyles.container}>
<View style={{width: '100%'}}>
<Text style={QualityStyles.leadersTitle}>Top Three Leaders</Text>
</View>
<View style={QualityStyles.topThree}>
{renderTopThree(topThree)}
</View>
<View style={{width: '100%'}}>
<Text style={QualityStyles.leadersTitle}>Employees</Text>
</View>
<View style={QualityStyles.remainders}>
{renderOthers(others)}
</View>
</View>
</ScrollView>
The code's pretty straightforward, with renderTopThree returning 3 components that will take up about 90% of the screen, and renderOthers will fit maybe one component on the screen, and the rest (while rendered and existent) can't be seen since I can't scroll. Anyone see what could be wrong?
I resolved the issue, I had a TouchableWithoutFeedback wrappping the entire Application, and it was blocking out any ability to scroll

ReactNative Nested Horizontal ScrollView ( nested twice)

The View Structure Below
<ScrollView horizontal pagingEnabled>
<View key={1}/>
<View key={2}>
<ScrollView horizontal={false} pagingEnabled>
<View key={'2-0'}>
<ScrollView horizontal pagingEnabled>{subviews here}</ScrollView>
</View>
<View key={'2-1'}/>
<View key={'2-2'}/>
</ScrollView>
</View>
<View key={3}/>
</ScrollView>
the problem is that,when I scrolled to the view[key:2], and its subview is view[key:'2-0'] right now, then the scrollview nested by view[key:'2-0'] will take over the gesture responder, and I will never ever got chance to swipe horizontally to the view[key:3] or back to view[key:1]. I've tried to set onMoveShouldSetResponderCapture to the outsidest scrollview to take over gesture responder while the insidest scrollview is on the edge. It will only work when I swipe slowly.
Is there anyway to make this work naturally ?
thanks, guys
Finally , I solved this problem be replacing the outsidest scrollview. I implemented the swpie-horizontally view with reanimated and react-native-gesture-handler. So I can totally control the outesidest scroll action.

React Native Expo How to Hide Status and bar make component take that place

I am not able to fill the status bar area with component. I tried to do it by hiding the status bar using <StatusBar hidden />. But this one leaves a white space there. For example I want to fill the green image the status bar.
TLDR: working project link
On the gist link (you've provided on the comment), I can see that you are using the following structure
<SafeAreaView>
<StatusBar ... />
<ImageBackground ...></ImageBackground>
</SafeAreaView>
If you want to hide the status bar and cover the whole screen with the image you need to change SafeAreaView to just View and also remove StatusBar component.
<View>
<ImageBackground ...></ImageBackground>
</View>
Cause SafeAreaView will dynamically put some padding at the top. So although you've put style={{ height: '100%', width: '100%' }} it will respect the padding of SafeAreaView cause it is the parent component here.
Also at this point, you do not need StatusBar, cause the StatusBas already has an image as background.

Horizontal ScrollView inside Vertical

enter image description hereThe structure of my code looks like the following:
<View style={{backgroundColor:'#FFF',flex:1,}}>
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={{paddingBottom:120}} stickyHeaderIndices={[6]}
>
...some content...
<ScrollView horizontal showsHorizontalScrollIndicator={false}
bounces={false}
scrollEventThrottle={16}
pagingEnabled={...}
decelerationRate={...}
snapToInterval={...}
disableIntervalMomentum={true}
snapToAlignment={"center"}
snapToOffsets={screens}
contentContainerStyle={{flexGrow:1}}
>
{horizontalContent}
</ScrollView>
</ScrollView>
but the content inside the horizontal scroll has different heights and all items become the same height as the largest, which creates a huge scroll space. How can fix this? Help pls
If you can see in my sample
Pink, red and blue bar have a specific height, they don’t grow to the containers max.
The turkey bar has a flex:1 which cause the container grow to the max, to prevent this behavior you could wrap the elements container with an view and pass the flex:0 style as i did for the black bar.