React Native Scrollview Stop Momentum? (expo) - javascript

I am using a ScrollView, and when I scroll and let go, it keeps scrolling because of momentum. I want it to only scroll when the finger is touching the screen, I do not want the momentum. Is this possible, if so, how?

Using decelerationRate prop with value 0 can help.
Based on the document, its value accept string normal | fast and floating number from 0 to 1 orderly from slowest to fastest.
<ScrollView decelerationRate={0}>
</ScrollView>
** I am using RN v0.59 **

Add 2 following properties to ScrollView:
snapToInterval={1}
disableIntervalMomentum={true}

Why not try this (RN 0.55)
<ScrollView
ref={r => (this.scrollView = r)}
onScrollEndDrag={e => {
return this.scrollView.scrollTo({ y: e.nativeEvent.contentOffset.y });
}}>
...
</ScrollView>

Related

HeaderRight Buttons are not clickable (React Native)

I am experiencing an odd bug with the React Native Navigation v5 headerRight Buttons. I currently have a TouchableOpacity set as a headerRight component in the react native navigation screen; however, the onPress event is not being triggered. There seems to be an invisible object in the middle of the header (title area) that has an absolute position, which prevents the onPress event from being registered. I tried playing around with the zIndex and headerMode values; however, the button is still not pressable. I can only press the button when it is placed on the far right of the screen (i.e. marginRight: 0). Any help would be greatly appreciated.
For reference, I am encountering the same issues as the following thread: https://github.com/react-navigation/react-navigation/issues/7052
Example of my Code
<StackNavigator.Navigator headerMode='screen'>
<StackNavigator.Screen
name='Home'
component={HomeScreen}
options={{
headerRight: () => (
<TouchableOpacity
onPress={() => {}}
>
<Text>Button Text</Text>
</TouchableOpacity>
),
}}
/>
</StackNavigator.Navigator>
Updating to the following packages seems to have resolved it for me:
"#react-navigation/stack": "5.9.3",
"#react-navigation/drawer": "5.9.3",
"#react-navigation/native": "5.7.4",
Try to give higher values to zIndex may be 100 or give headerMode: float if that not also not works try updating your packages .

Using React-native-picker-select headless component

I'm trying to use React-Native-Picker-Selects headless component for both iOS and Android. According to the docs found here:
you can pass children (such as a custom button or input) for the component to wrap (for both iOS and Android
Here is a sample of my code:
import React, { Component } from 'react';
import {
View,
Text,
} from 'react-native';
import RNPickerSelect from 'react-native-picker-select';
<View style={{flex:1}}>
<RNPickerSelect
placeholder={{}}
items={MyList}
onValueChange={(itemValue, itemIndex) => {
console.log('itemValue')
}}
style={{...pickerSelectStyles}}
>
<View style={{backgroundColor:'purple', flex:1, justifyContent:'center', alignItems:'center'}}>
<Text>
Test Text where I should be able to touch to get things to happen
</Text>
</View>
</RNPickerSelect>
const pickerSelectStyles = StyleSheet.create({
headlessAndroidContainer: {
flex:1
}
});
<View style={{height:height * 0.5}}>
<Text>test</Text>
</View>
</View>
const pickerSelectStyles = StyleSheet.create({
viewContainer: {
flex:1,
backgroundColor: 'purple',
},
headlessAndroidContainer: {
backgroundColor: 'purple',
flex:1
}
});
What I expect to happen is that on my screen I see two-section, half purple, and half white. The purple section has the text saying that things should happen, and the white section should have Tested. I should be able to tap anywhere on the purple section and my picker with MyList should come up.
This is working as expected on a simulator, but not on a real android device. on a real device, it seems that I'm able to tap around on the purple area, and the picker shows up very sporadically. Any assistance would be greatly appreciated!
Edit: Forgot to mention that this is specifically an android problem, it works on both real and simulated iPhones
Seems like having the RNPickerselect wrapped in a TouchableWithoutFeedback breaks it for some reason, once outside that tag it worked fine.
Adding the latest version (version 5.0) seems to fix this issue. The version I added was 4.4, and I added it to my project maybe 10 days ago. The newest version was released about a week ago, and seems to solve this problem.

Conditional Styling in React Native

I have this ImageBackground tag in my React-Native App.
const{height,width} = Dimensions.get('window);
const navHeight = ExtraDimensions.get('SOFT_MENU_BAR_HEIGHT');
render(){
return(
<ImageBackground source={Images.bg} style={{width=width+48,height=height}}>
//content
</ImageBackground>
);
}
The number 48 is the height of the default Android navigation bar (the one contains BACK button). The navHeight is to detect the height of navigation bar on the device (refer here:https://github.com/Sunhat/react-native-extra-dimensions-android).
Since there are now devices with no navigation bar, i want to make a conditional styling in the ImageBackground style to take style={styles.bg1} when there is a value of navHeight and take style={styles.bg2} when there is no navHeight value.
May i know where and how should i implement the styling? thanks
My current wrong way of doing it is
<ImageBackground source={Images.bg} style={navHeight=0 ? styles.bg1 : styles.bg2}>
There is a syntatical error, for comparison you have to use ==.
Try this,
<ImageBackground source={Images.bg} style={ (navHeight==0) ? styles.bg1 : styles.bg2}>
Moreover, i would recommend you using Image tag and append a child component to it by using position="absolute". Because some styling props like borderRadius don't work in the case of ImageBackground tag.
I hope this helps you !

How to rebuild the iOS Picker animation in React Native

Is there a way in React Native to rebuild the iOS picker component completely in Java Script? I don't need the common picker, but a normal scroll view with a similar fade-out effect like the iOS picker.
EDIT – I think I have not explained my initial answer exactly enough. This is why I complete it here:
I want to build a scroll view that takes over the whole screen. It's not supposed to give the user the possibility to elect some item, like the the iOS Picker does. Nevertheless, it's supposed to be a 'normal' scroll view, that shows the user some information, e.g. different chats, tasks, news and so on.
The only difference to React Native's common scroll view should be the fade-out effect at the top: When the user scrolls the content up, it should not just leave the screen at its top edge, but it should use the iOS Picker's fade-out effect (see picture).
This fade-out effect is made up of two parts: First of all, it raises the content's transparency with a decreasing y-coordinate. Furthermore, this content seems to escape into the third dimension.
My problem is, that I don't see a way to achieve this three-dimensionality of the content in React Native. I've to add, that the content in my scroll view does not consist of small, equally sized items (like e.g. the texts 'Item 1', 'Item 2', 'Item 3',...), but of bigger items with different sizes like images or whole textboxes.
You can use this NPM module to get what you want. That module works the same in Android and iOS. Do not reinvent the wheel :)
EDIT: Now I've understood what you want. You can try this snack that I've made for you:
https://snack.expo.io/r1qnxSt9m
Of course you need to improve it, but it's a beginning.
You can achieve the desired effect with the Animated api. The idea is to set different input ranges to the items in your list. You then hook the opacity to the scroll value of your ScrollView (or any list component). I have simplified the code, but it should be enough to demonstrate the idea.
The example below only demonstrates an opacity effect, but you could easily add a translate effect to get the exact animation that you are looking for.
const data = []; // array that contains the text
const items = [];
for (let i = 0; i < data.length; ++i) {
const distanceFromViewCenter = Math.abs(i * ITEM_HEIGHT);
const inputRange = [
-distanceFromViewCenter - 2 * ITEM_HEIGHT,
-distanceFromViewCenter - ITEM_HEIGHT,
-distanceFromViewCenter, // Middle of picker
-distanceFromViewCenter + ITEM_HEIGHT,
-distanceFromViewCenter + 2 * ITEM_HEIGHT,
];
items.push(
<Animated.View
style={{
opacity: this._scrollValue.interpolate({
inputRange,
outputRange: [0.0, 0.3, 1.0, 0.3, 0.0],
}),
}}
>
<Text style={{ height: ITEM_HEIGHT }}>{data[i]}</Text>
</Animated.View>
)
}
<ScrollView
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: this._scrollValue } } }],
{ useNativeDriver: true }
)}
>
{items}
</ScrollView>

React Native ScrollView/ListView RefreshControl intitially ugly on top right

I'm having a RefreshControl attached to a ScrollView. It all works as expected but initially (when I didn't start scrolling), there's always showing a RefreshControl on the top right. When I start scrolling, it disappears.
Any idea how to get rid of that?
Code is nothing special, if you want, i'll give it here:
// ...
export default class SomeList extends React.Component
{
// ...
render() {
return <View style={{flex: 1}}>
<CustomNavbar />
<ScrollView
style={{marginTop: 35}}
refreshControl={
<RefreshControl
tintColor={$.config.colors.style}
onRefresh={() => this._refreshList()}
refreshing={this.state.listRefreshing}
/>
}
>
{this._renderItems()}
</ScrollView>
</View>
}
}
This is a bug in react-native which was introduced in version 0.31 or so.
It was fixed in version 0.34.1 (see this commit), so I guess you're using a previous version.
If you do not wish to upgrade, you can temporarily solve it by settings the background color of the refresh control to transparent:
<RefreshControl style={{backgroundColor: 'transparent'}}/>

Categories

Resources