Add content in bounce margin of ScrollView in React Native? - scrollview

In my app I'm using <ScrollView /> to view pages of a book scrolling horizontally. When a user gets to the end of the <ScrollView /> there is a bounce that shows a white area to the right that is only visible if the user drags the last page to the left. I want to add some text there that says "The End" vertically. How can I add content to the right of the <ScrollView /> in the bounce area?

I ALMOST figured it out. This is close but shows up in the right side of the last page but not off the page on the right in the bounce area. I want it to show up "to the right of the page" not "on the right side of the page." Any other ideas?
Create a <View style={styles.end} /> with this style:
theEnd: {
position: 'absolute',
top: 0,
right: 0,
width: 100,
height: 768, // Device height
alignItems: 'center',
}
Place it right before the <ScrollView /> and put whatever you want to show inside of the View component with the "theEnd" style.

This probably doesn't apply to your content, but I had the same situation except with a large image for the ScrollView content. I wanted both horizontal and vertical scrolling, where the edge of the image would show up only in the bounce margin. I figured out that the scale transformation works great for this:
<ScrollView horizontal={true}>
<Image
source={require('./img/map.jpg')}
style={{transform: [{scale: 1.1}]}}
/>
</ScrollView>
So the image takes up 110% of the height and width of its box (which is then inside a yet smaller ScrollView).
EDIT: FYI, after testing, discovered this only works on iOS, not Android. (Android won't allow vertical scrolling if you set horizontal to true, and also I think it didn't render the parts outside of the normal viewing area, so the bounce margin was empty.)

there is a prop for this called contentContainerStyle
<ScrollView
horizontal={true}
contentContainerStyle={{
paddingLeft: 25,
paddingRight: 25,
}}>
*** CONTENT ***
</ScrollView>

Related

Change react-native ScrollView color

I have a problem with ScrollView in React-Natives. I've already looked for it in the react-native docs, but still unable to find it. Because of this I need to include an image since I don't even know how to call it.
Is it possible to change the "purple" color in this picture? How? And what is this "purple" thing called?
Here's my code to give a clue.
The ScrollView:
<ScrollView
horizontal={true}
showsHorizontalScrollIndicator={false}
style={style.scrollContainer}
endFillColor="#000"
>
The styles
scrollContainer: {
marginTop: 20,
marginHorizontal: 10,
color: "#fff",
},
Thank you
This is the overScroll glow effect on android devices and can be disabled using the overScrollMode prop. You need to set it to never as follows.
<ScrollView
horizontal={true}
showsHorizontalScrollIndicator={false}
style={style.scrollContainer}
endFillColor="#000"
overScrollMode="never"
>
I have created a little snack that showcases this prop. Notice that I have disabled this for the horizontal scrollview and enabled it for the vertical scrollview.
Changing the color is only possible by adding <item name="android:colorEdgeEffect">#E53644</item> to your styles.xml as discussed here, whereby #E53644 is the hexcode of the color of choice.

Handling SafeArea in ReactNative on iPhone X

In my ReactNative app, I'm using "SafeAreaView" to restrict my content in the visible area. My app runs in landscape mode. Look at the image
My app has FlatList with 2 Items rendered. If you notice the FlatList (in green color), on the left it has some padding of 20 pixels and on the right, it has notch (though it has padding of 20 pixels to the border). Due to notch on right my FlatList don't seem to be centered.
Is there a way to handle the content size considering the notch area?
try wrapping your Flatlists with an inner View between the Flatlists and the SafeAreaView and add the padding the inner View e.g
<SafeAreaView style={{flex: 1}}>
<View style={{flex: 1, padding: 24, justifyContent: 'center', alignItems: 'center'}}>
{/* your flatlists here */}
</View>
</SafeAreaView>
this should make it look more natural.
For iOS, you can use this package: https://www.npmjs.com/package/react-native-iphone-x-helper
getBottomSpace() and getStatusBarHeight()

How can I detect when the user gets a View and do something after getting this position on React Native?

I have a ScrollView with some Views inside it, but I want to start an animation when the user gets to specific View and after it starts my animation.
Example:
<ScrollView style={{ width: DeviceWidth, height: DeviceWidth * 0.5 }}>
{/* When user position scroll is here,
is where I want to start the animation,
not since the page is loaded */}
<View style={{
width: DeviceWidth * 0.4,
height: DeviceWidth * 0.4,
resizeMode: "contain",
}}>
<ProgressBarAnimated
width={barWidth}
value={65}
backgroundColor="#F68D29"
height={40}
barAnimationDuration={6000}
/>
</View>
</ScrollView>
Instead of using a ScrollView you can instead use a FlatList, this gives you a lot more support for the type of indexing you're trying to do.
To detect when a user reaches a specific point you can use onViewableItemsChanged and the define which viewable items need to be on screen in order to trigger your animation.
FlatLists also support a number of build in animations like scrollToEnd or ScrollToIndex which may be helpful.

Clickable Background underneath a ScrollView [React Native]

So, I want to create a layout similar to whats below. [Refer the Image]
So the background has a full screen MapView (React Native Maps) with Markers over it, which needs to be clickable.
And there is a Scrollview with full screen height over the MapView which initially has some top-margin associated with its contents.
But the issue if I arrange my Views this way, the Markers on the map are not clickable in the initial state.
<View>
<MapView>
<Marker clickEventHere></Marker>
<Marker clickEventHere></Marker>
</MapView>
<ScrollView fullscreen>
<View marginTop></View>
</ScrollView>
<View>
I am unsure if its really possible to solve this out.
Initial State
After Scrolling
Solution Tried
yScrolled = event.nativeEvent.contentOffset.y;
yValue = this.state.yValue - yScrolled;
upwardScroll = yScrolled > 0;
if(upwardScroll && (yValue > 0)){
this.setState({
yValue: yValue
});
}
if(yScrolled === 0){
yScrolled = -10;
}
if(!upwardScroll && (yValue <= scrollViewMarginTop)){
yValue = this.state.yValue - yScrolled;
console.debug("UPDATE DOWNWARD");
this.setState({
yValue: yValue
});
}
I'd start with adding absolute positioning to your ScrollView, (position: absolute) starting at whatever y coordinate you would like. I would make this y value a state, eg
yValue: new Animated.Value(start_value) or simply yValue: start_value
I would then use ScrollView's prop onScroll event to handle the change in this y coordinate, for example for the first 100 pixels of a scroll it would simply change the yValue instead of scrolling the view.
This should enable you to press the markers you have in your parent view, and use the same component structure that you have provided.
Note: You would need to do this for collapsing the scrollview also.
Note2: if this doesn't give you the result you were looking for, i'd suggest looking into using some sort of collapsable component for this task, eg https://github.com/oblador/react-native-collapsible
Hope this helps
EDIT: To collapse the scrollview you could first identify if the scroll direction is downwards ( which i think youve done via upwardScroll ) and then..
1) Either simply add the content offset to your yValue
2) If you used Animated.Value for yValue, you can have an animate function that animates the scrollview downwards to your desired position. I think this would look nicer as the user would only need a simple downwards flick to collapse the view, which seems like the industry standard.
There is also a library that is called react-native-touch-through-view that can do this for you. This it how it works basically:
<View style={{ flex: 1 }}>
// Your map goes here
</View>
<TouchThroughWrapper style={{
position: 'absolute'',
top: 0,
left: 0,
width: '100%',
height: '100%',
}}>
<ScrollView
style={{
backgroundColor: 'transparent',
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
// Maybe in your case is flex: 1 enough
}}
bounces={false}
showsVerticalScrollIndicator={false}
>
<TouchThroughView
style={{
height: 400, // This is the "initial space" to the top
}}
/>
// The "slide up stuff" goes here
</ScrollView>
</TouchThroughWrapper>
For example, this then can look like this:
So the map is overlayed by the TouchThroughView that passes all the events right to the view behind. In my case this worked better than using pointer-events box-none.

How to show hidden view with translateX in React Native

Here is the code:
<View
style={{transform: [{translateX: this.state.translateX}], width: '120%'}}>
<View style={{width: '20%'}}>{someText}</View>
<View style={{width: '80%'}}>{someText}</View>
<View style={{width: '20%'}}>{someText}</View>
</View>
this.state.translateX was respond to swipe gesture which worked fine, the first two View did move but the last View was not visible (or not moved?). I want to show the last View when this.state.translateX changed. But it seems not being properly rendered?
It is because Android does not render element which is off screen. Solution is place the element in screen with position: 'absolute' and then use translateX to hide it from screen.