Using React-native-picker-select headless component - javascript

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.

Related

How can you ensure flex shrink in react-native (and how can you debug react-native styles in general)?

I'm running a RN app using native-base for styling. I have four elements on my homepage: a header, a tab view from vreact-native-tab-view that contains a ScrollView that takes up about 70% of the viewport, and two smaller 100% width elements at the bottom.
However, the scrollview fills up more than 100% of the viewport and the two smaller elements get pushed to the bottom.
I looked in my element inspector and can apply a flexShrink to some of the many divs, but I'm not sure which one that is in my code because it's div hell when you use react-native. React devtools also has the same problem, except it's View hell.
So, two questions:
How can I ensure the scroll container doesn't fill up more than it should on the page?
How can I effectively debug react native when both chrome and react dev tools are a mess?
For reference, here's how I've styled so far:
Home.tsx:
<View flex={1}> // applied a flex for the entire homepage
<TabView
navigationState={{ index, routes }}
renderScene={renderScene}
renderTabBar={renderTabBar}
onIndexChange={setIndex}
initialLayout={{ width: layout.width, height: "100%" }}
/>
<View width="100%">
<Center width="100%">
<StrengthSlider />
</Center>
<AdMobBanner
...props
/>
</View>
</View>
Teas.tsx:
<View flex={1} bg="white">
<ScrollCards teas={blackTeas} />
</View>
ScrollCards.tsx:
<ScrollView>
<Center>
{teas.length > 0 &&
teas.map((teaObj) => (
<TeaCard id={teaObj.id} teaData={teaObj.data} key={teaObj.id} />
))}
</Center>
</ScrollView>
EDIT:
Code Sandbox link: https://codesandbox.io/s/gracious-sammet-l4tqz?file=/src/App.js&resolutionWidth=402&resolutionHeight=675
Note that the admob footer remains underneath the cards content. It should be sticky and remain always at the bottom of the screen. I also noticed that when I'm not using the header from the MainStackNavigator the footer works as intended - i.e. it remains sticky at the bottom - but I don't see why using the header (AppBar) component should interfere with my footer.
The proper solution to get the result you want is to add a flexBasis to the TabView like:
<TabView
style={{ flexBasis: 0 }}
// rest of the code
/> ​
Why?
The TabView has a default style of flex: 1, overflow: 'hidden' (see source code) causing it to expanded to the size of its biggest child. The flexBasis prevents this and makes sure the tabview get the correct height.
Resource: This is a nice article about flexBasis vs width/height: https://mastery.games/post/the-difference-between-width-and-flex-basis/
Debugging styling in React-Native doesn't have the best developer experience. There are some things you can use to help you with debugging styling:
RN inspector: As Berci mentioned, React native has a dev menu where you can select "show inspector" that kinda acts like "inspect element" in a browser. It is a good tool to debug elements you can see, it also helps with debugging input/tab events.
Color: Most often I just use old fashioned colored borders & background to get a clear view of where elements are & their size/overlaps.
Comments & Simplify: Feel free to comment out components you're not interested in and replace complex components/views like ScrollCards with just a simple colored view. This can help prevent multiple behaviours from influencing the thing you're trying to debug
Browser inspect & React devtools: If you happen to run your RN app in the browser, then getting familiar with those tools will help you loads. Just keep in mind that React & React-Native isn't the same.
When you debug visuals, the best way is start at the top layer and work you way down. Color the elements & feel free to comment out elements to get you a clearer view of the problem. Keep digging down until you find the problem, don't be afraid to look into the source code of the packages you use, it often helps clarify (unexpected) behaviours.
You could try to replace
<View flex={1}> // applied a flex for the entire homepage
in Home.tsx with
<View flex="1 1 0">
Working example here (is your code with that line modified).
As for debugging I can only suggest what is already suggested on react native Debugging page. Have you tried React Developer Tools yet? In chrome you can also add it as an extension from this link.
I am not sure if there is any difference between chrome extension and the npm package but the extension was enough for me at least (for now).
The only problem is that I also struggled debugging on codesandbox since the extension is definitely not working on javascript online editors (but probably the npm package doesn't either for this specific case)
Try this - https://snack.expo.dev/fL0OgQ9uS
import React from 'react';
import { View, Image, StyleSheet,ScrollView,Text } from 'react-native';
const styles = StyleSheet.create({
container: {
paddingTop: 50,
flex:1,
backgroundColor:'aqua',
},
tinyLogo: {
width: 200,
height: 200,
},
header:{
backgroundColor:'green',
paddingBottom:20,
},
footer:{
backgroundColor:'green',
paddingTop:20,
}
});
const DisplayAnImage = () => {
return (
<View style={styles.container}>
<View style={styles.header}><Text>header</Text></View>
<ScrollView>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
</ScrollView>
<View style={styles.footer}><Text>footer</Text></View>
</View>
);
}
export default DisplayAnImage;

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 .

Set ImageBackground using Stack Navigator

What I'm facing:
I have a StackNavigator in which I want to set a ImageBacgkround to all it's children screens. The problem is, I've already setted my StackNavigator cardStyle: { backgroundColor: 'transparent' }, following React Navigation Docs, and wrapped it inside a ImageBackground but still can't get it working.
What I've tried:
//My navigator component is more complex, but the concept looks something like this
//for both navigators
const Stack = createStackNavigator();
const MyStackNavigator = () => (
<ImageBackground source=('../assets/my-background.png') resizeMode='cover' style={{flex: 1}}>
//If I change BackgroundColor to 'red' or anything like that, it works fine
//so I think the problem isn't related to styling properties
<Stack.Navigator screenOptions={{cardStyle: { BackgroundColor: 'transparent' } }}>
<Stack.Screen name='Screen1' component={Component1}/>
<Stack.Screen name='Screen2' component={Component2}/>
<Stack.Screen name='Screen3' component={Component3}/>
</Stack.Navigator>
</ImageBackground>
);
export default App() => (
<MyStackNavigator />
);
I've done the same thing in a DrawerNavigator inside my navigator component passing sceneContainerStyle: { backgroundColor: 'transparent' } }} and it actually works. It seems like my StackNavigator ain't rendering it's parent components correctly.
One of my StackNavigator's screens:
One of my DrawerNavigator's screens:
Both navigator's screens layout are wrapped in a transparent container View, so as you can see, the drawer screen is rendering background correctly but the stack screen isn't. Maybe I'm passing wrong props to my StackNavigator?
well with react-navigation 6 you can use the theming option to customize the look for the background to be transparent (Default is rgb(242,242,242)) use a NavigatorContainer to apply the theme
here is an answer that may help

Not able to set ShadowColor in react-native android

Environment
Environment:
OS: macOS High Sierra 10.13.1
Node: 8.9.1
Yarn: 0.17.10
npm: 5.6.0
Watchman: 4.7.0
Xcode: Xcode 9.2 Build version 9C40b
Android Studio: 2.3 AI-162.4069837
Packages: (installed)
react: 16.0.0
react-native: 0.51.0
Steps to Reproduce
Run this code
import React, {Component} from 'react';
import {View, Text, TouchableOpacity} from 'react-native';
class App extends Component {
render() {
return (<View style={styles.container}>
<View>
<TouchableOpacity style={[styles.boxShadow, shadow]}>
<Text style={styles.text}>LOGIN</Text>
</TouchableOpacity>
</View>
</View>);
}
}
const shadow = {
shadowColor: '#30C1DD',
shadowRadius: 10,
shadowOpacity: 0.6,
elevation: 8,
shadowOffset: {
width: 0,
height: 4
}
}
const styles = {
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
boxShadow: {
width: 200,
height: 50,
borderRadius: 10,
backgroundColor: '#ed7171',
justifyContent: 'center',
alignItems: 'center'
},
text: {
color: '#ffffff'
}
};
export default App;
Expected Behavior
Is there way to achieve like this Shadow in Android
as shadow Props of react-native only supports in iOS
color need to be changed
Tried elevation but can not change default greyed color
able to achieve in ios with shadowColor props but not in android as it is only support iOS
Actual Behavior
See sample code and preview.
It should be work for android too.
Shadow color is always grey, however I tried to change..
Reproducible Demo
This is sample snapshot in which I can only get shadow with elevation with only grey color [default].
As of now the only ways to add shadow are using
elevation :value
for Android version >5
or to use
https://github.com/879479119/react-native-shadow
This is a third party plugin but it supports colour although it doesn't support RGB till now
Since there is no "shadow" attribute in style list of Android, if we want to add a shadow effect on a component, we must patch a PNG-24 picture, but it's so non-graceful; therefore here comes an SVG shadow plugin to help with this problem. We suggest you to use native shadow on iOS
**
You can use LinearGradient trick
**
https://hashnode.com/post/is-there-any-good-alternative-to-elevations-for-android-in-react-native-cjc600tva00pfuzwup50xv01z
Updated:
your now able to add shadow color in react native 0.64
Try
{
backgroundColor:"#fff",
elevation:4,
shadowColor:"blue",
}
It's not exactly similar to expected behaviour by that's the best we have right now without using any external packages.
You can use the react-native-shadow-2 library to easily add different colored shadows, even gradient shadows
<Shadow distance={4} startColor='rgba(42, 255, 42, 0.4)' finalColor='rgba(42, 255, 42, 0.05)' >
<View style={{width:200,height:80}}>
<Text>TEST!</Text>
</View>
</Shadow>
Use elevation to implement shadows on RN Android. Added elevation prop #27
<View elevation={5}> </View>

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