There is a problem with speed of Picker component rendering after arrow-down icon is touched. User can feel a lag. The problem is present when there is lots of picker items. What could I do to enhance the user experience in this case? Could a portion of Picker items be rendered first somehow? React-native-picker-android is used here, maybe this is the case with this component but I'd like to know best practices to deal with this performance issue.
When arrow-down is touched this.state.modal is changed to true and Picker component reacts to this change so that it appears on the screen.
{this.state.modal ? <View style={{height: 200, backgroundColor: '#E8E8E5'}}>
<Picker
pickerStyle={styles.picker}
itemStyle={{color: '#F99704'}}
selectedValue={this.props.value}
onValueChange={this.props.onChange}>
<Picker.Item label={'07:00'} value={'07:00'} />
<Picker.Item label={'07:00'} value={'07:00'} />
<Picker.Item label={'07:00'} value={'07:00'} />
<Picker.Item label={'07:00'} value={'07:00'} />
.
.
.
Related
I'm trying to make a dropdown select box. I'm using react-native's Picker.
I'm using the following code:
<Picker mode={"dropdown"} selectedValue={"test2"} style={{height: 50, width: 125}}>
<Picker.Item label="test" value="test"/>
<Picker.Item label="test2" value="test2"/>
<Picker.Item label="test3" value="test3"/>
<Picker.Item label="test4" value="test4"/>
</Picker>
The Picker still appears to not be a dropdown.
I'm using a IPhone X on the simulator.
The mode props is only supported on Android. From the docs:
mode
On Android, specifies how to display the selection items when the user taps on the picker:
'dialog': Show a modal dialog. This is the default.
'dropdown': Shows a dropdown anchored to the picker view
https://facebook.github.io/react-native/docs/picker#mode
I found out that mode only applies to Android. https://www.npmjs.com/package/react-native-picker-select did the job.
I have a bunch of text inputs:
<View style={styles.container}>
<View style={styles.textBoxContainer}>
<TextBoxMA
style={styles.textBox}
placeholder={Labels.USERNAME_PLACEHOLDER}
value={userName}
onChangeText={this.handleTextChange("userName")}
/>
</View>
<View style={styles.textBoxContainer}>
<TextBoxMA
style={styles.textBox}
placeholder={Labels.EMAIL_PLACEHOLDER}
value={email}
onChangeText={this.handleTextChange("email")}
/>
</View>
//here I need to put a Picker, or select element in html terms
</View>
Now, if I put a Picker like this:
<View
style={styles.textBoxContainer}>
<Picker
selectedValue={documentType}
onValueChange={this.handleDocumentTypeChange}
>
<Picker.Item label="ID" value="1" />
<Picker.Item label="Passport" value="212" />
</Picker>
</View>
I get a nice, clean picker in Android. But in iOS I get a picker whose items overlap with the rest of the text boxes and it takes a lot of space. So it destroys all the layout.
I understand that native components corresponding to a dropdown list in the two platforms are different. But how do you handle this?
I've taken a look at AirBnB's app which's been written in React native. In iOS, the view containing the picker slides from the bottom when a corresponding field is clicked (like the Gender field. It looks like a text input but it's not. It just causes the picker to show). And in Android, it's just a modal view with items in the radio button form. They've probably done lots of extra work to achieve that.
Do I need to show picker depending on the platform or is there a built in way to achieve this?
You can use community solutions like
react-native-picker-select
Or
react-native-picker-modal-view
Or
react-native-picker
Or you can build your own solution and do what ever you want you can style and position and even animate your component as you like.
I'm trying to display a dropdown menu in a React Native android app. I used React Native Picker for the purpose, and it seems very limited in styling and positioning the dropdown menu. I cannot get the menu to pop up below the carret (the down arrow button) position.
I tried setting the margin with hope to push the menu down, to no avail.
<Picker
// selectedValue={stateValue}
style={{
height: 36,
width: 261,
}}
onValueChange={itemValue => {
console.log('item value ', itemValue);
}}
>
<Picker.Item key={-1} label={'Search By...'} value="first" />
{this.searchCategory.map((item, index) => (
<Picker.Item key={index} label={item} value={item} />
))}
</Picker>
</View>
The menu always covers the Picker component. I want it to appear below the Picker.
Actual behavior:
Expected behavior:
After some research, this is an Android limitation and it seems there's little we can do with React Native Picker. Some custom packages may give us more control such as https://www.npmjs.com/package/react-native-picker-select, or https://github.com/sohobloo/react-native-modal-dropdown.
I'm having an issue with the React Native Picker.
My problem is that the selectedValue in the Picker does not show on small screens! On big screens it works just fine, but at a certain width, the selectedValue is not rendered, only the little downwards arrow.
When I manually set the width of the picker to be 100, it works fine, however, if the width is set to 50 (which is what I need), the selectedValue doesn't render, only the arrow downwards.
My code looks like this:
<Picker
selectedValue={props.selectedCurrency}
style={headerStyle.picker}
onValueChange={props.setCurrency}
>
<Picker.Item label="USD" value={Currency.USD} />
<Picker.Item label="EUR" value={Currency.EUR} />
</Picker>
And then the styles look like this:
picker: {
flex: 1,
width: 50,
},
I have figured out one solution, which is to render a component besides the Picker, but then the Text isn't clickable, which isn't the best UX design..
Can anyone help? I just want the selectedValue to render on both small and big screens.
Thank you very much in advance.
Unfortunately, if you need a minimum width to display correctly your items you do not have much choices. You can define a style for your items and maybe lower their size or use a font which render them lower. For example :
<Picker
selectedValue={props.selectedCurrency}
style={headerStyle.picker}
itemStyle={headerStyle.pickerItem}
onValueChange={props.setCurrency}
>
<Picker.Item label="USD" value={Currency.USD} />
<Picker.Item label="EUR" value={Currency.EUR} />
and for style
picker: {
flex: 1,
width: 50,
},
pickerItem: {
fontSize: 12
}
Or/and maybe you will have to change your UI in order to display the picker elsewhere in your screen to be sure to have enough space to display it correctly.
Hope this helps !
from this answer, you need to convert selected value to string.
<Picker
//...
selectedValue={props.selectedCurrency ? props.selectedCurrency.toString() : null}
//...
>
I'm trying to add some styling to react-native picker, like underlying and set placeholder, but unable to do so.
const styles = StyleSheet.create({
picker: {
textDecorationLine: 'underline'
}
});
<Picker
style={[styles.picker]}>
<Picker.Item label="Country" value="" />
<Picker.Item label="United States" value="US" />
<Picker.Item label="India" value="IN" />
</Picker>
If i use value="", then it shows country as a selectable value, which i don't want.
textDecorationLine is not able to set the underline styling to picker.
Basically, i am looking to create something like this,
where, i can set the color of placeholder as well.
Thanks in adv.
Picker and Picker item's styling is handled natively on Android. You need to define style for Android's SpinnerItem in android/app/src/res/styles.xml see: How to style the standard react-native android picker?
I tried to test the underline but couldn't seem to find anything that worked. Here is couple of workarounds Android spinner with underline appcompat
However, I would simply use react native's components to our advantage. I'd create a new component that wraps React Native's Picker and put the picker in a View with the underline style that renders a placeholder if the Picker's value is undefined.
You can also use this one for make more attractive to your react-native picker.You can add styles to your view so it can easily make changes to your picker.
import React, { Component } from 'react';
import { View, Picker } from 'react-native';
export default class DropdownDemo extends Component{
state = { user: '' }
updateUser = (user) => {
this.setState({ user: user })
}
render(){
return(
<View
style={{
width: 300,
marginTop: 15,
marginLeft:20,
marginRight:20,
borderColor: 'black',
borderBottomWidth:1,
borderRadius: 10,
alignSelf: 'center'
}}>
<Picker
selectedValue={this.state.user}
onValueChange={this.updateUser}
>
<Picker.Item label="Male" value="Male" />
<Picker.Item label="Female" value="Female" />
<Picker.Item label="Other" value="Other" />
</Picker>
</View>
);
}
}
You need to modify your activity theme as follows:
<!-- Base application theme. -->
<style name="AppTheme">
<!-- Customize your theme here. -->
<item name="colorAccent">#color/colorAccent</item>
<item name="android:spinnerStyle">#style/Base.Widget.AppCompat.Spinner.Underlined</item>
...
</style>
The colorAccent controls the color of the underline, and using #style/Base.Widget.AppCompat.Spinner.Underline provides the underline on your Picker.
You can use this technique to set the styling on almost any android component in React. android:editTextStyle, android:textViewStyle, etc.
Unfortunately, because the React Picker extends Spinner and not AppCompatSpinner, the styling will be a bit different if you're running on API < 21.
The issue here is an assumption that Picker has the properties and styling of TextInput, which it does not. There's a related question here: Have a placeholder for react native picker where a comment outlines what you'll need to render something akin to placeholder text.
In order to achieve something like to textDecorationLine you might apply a borderBottomWidth style to the component.
Also, remember to bind the selectedValue and onValueChange props:
selectedValue={this.state.country} onValueChange={(country) => this.setState({country: country})}>
This is the closest I can get on iOS: https://snack.expo.io/r1L7DGb1Z
Few things to note:
1) there is itemStyle property for setting the specific style for single picker item
2) In order to get down arrow, you have to mimic it manually. You would probably like to attach it's functionality with TouchableHighlight (which isn't done in the example)
3) This doesn't look similar in the Android, so you probably need to append additional, platform specific styling.
This piece of the code is working on my machine:
<View style={{borderBottomWidth:1, borderColor: 'rgb(204, 204,
204)',width: "28%"}}>
<Picker
selectedValue={this.state.pickerValue}
style={[styles.textInputBox]}
onValueChange={this.onChange}>
<Picker.Item label="+31" value="+31" />
<Picker.Item label="+41" value="+41" />
<Picker.Item label="+51" value="+51" />
<Picker.Item label="+61" value="+61" />
</Picker>
</View>