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}
//...
>
Related
In my React Native Project, I am trying to make some kind of lists using Flatlist or sometimes using map method, for executing JSX Element. I am getting the result correctly, But there is a bit of a problem in separate.
Let's take chatting app example, When we open WhatsApp there are a lot of people showing up, but there is also a tiny separator after each item, That looks great, Now exactly when I try to put that separator in my React Native application using ItemSeparatorComponent attribute in Flatlist, It's working but still in some places, meaning in some items that separator not showing up, its looks missing, it feels that there is no border/separator. And actually what's going on is that, the below item from that separator which is hidden or which height looks smaller than others, that below View go a little bit towards the upside, so the separator gets to hide, That's the main problem, Why is that happening, I tried everything but still, I am getting that UI problem.
Here is code example:
<FlatList
data={actionSheet._data}
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
keyExtractor={(_, index) => index}
renderItem={({item, index}) => <ActionSheetClickableItem data={item} index={index}/> }
ItemSeparatorComponent={() => (
<View
style={{
height: 1,
width: '100%',
backgroundColor: 'red'
}}
/>
)}
/>
OR
<ScrollView>
{
actionSheet._data.map((item, index) => (
<>
<ActionSheetClickableItem data={item} index={index} key={index}/>
<View
style={{
height: 1,
width: '100%',
backgroundColor: 'red'
}}
/>
</>
))
}
</ScrollView>
So according to the above code, I know for sure, that everything is correct, But why is that separator get hidden, If we look at this picture in the area of the green rectangles, there is no border showing up, Why... I want to show it here, I tried to put zIndex property, that trick working correctly but that isn't the solution, It have to correct view as we expecting, why its behave like this, any solution??????
I was facing the same issue.
That might be with Emulator or Your screen.
You can use also increase the height of itemSeparater or make the background color more darker.
If you check it in real device then it displays all the separaters.
I have implemented a react-native-material-textfield TextField which is focusing on taps outside of the TextField component (but within a certain distance from the component). Why does this happen?
I have tried limiting the size of both container and inputContainer, as well as wrapping the TextField in a View shrinked to fit the TextField component.
This is my implementation of the TextField:
<TextField
ref={this.passwordRef}
secureTextEntry={true}
containerStyle={{width: 300, backgroundColor: 'green'}}
inputContainerStyle={{width:300, backgroundColor: 'yellow'}}
tintColor={'rgba(0, 0, 0, .38)'}
fontSize={20}
enablesReturnKeyAutomatically={true}
autoCapitalize='none'
autoCorrect={false}
returnKeyType='done'
label='Password'
error={this.state.errors.password}
onChangeText={this.handlePasswordChange}
value={this.state.password}
/>
The expected behavior is that the TextField should focus when tapped, not when the target of a tap is outside the component.
Finally figured this out. Even though no overflow was visible neither for the TextInput (referenced by style) nor the InputContainer (referenced by inputContainerStyle), setting the overflow prop to hidden for the containerStyle fixed my problem.
set your style prop equal to the other widths:
style = {{width: 300}}
If you have a width it is also best to specify a height if your component is not wrapped in a View.
I've been trying to make a growing textinput with multiple lines now for a while, and is now finding my app in a situation where the keyboard blocks the text when entering a new line on the textinput. I've tried solutions ranging from KeyboardAwareScrollView-based solutions to ScrollView solutions, but alas nothing I've tried yet have worked.
I would really appreciate if someone could provide me with a solution that works for both android and iOS.
What I have now is a view with a textinput with multiline prop
<View style={{ height: this.state.height, flex: 1 }}>
<TextInput
{...otherProps}
placeholder="Skriv här"
placeholderTextColor="rgba(0,0,0,0.3)"
blurOnSubmit={false}
multiline
onContentSizeChange={this._onContentSizeChange}
style={[styles.textInputStyle, { height: this.state.height }]}
/>
</View>
with the _onContentSizeChange function as follows:
_onContentSizeChange = (event): void => {
const height = event.nativeEvent.contentSize.height;
this.setState({ height });
}
Problem illustrated with pictures:
imgur album
KeyboardAvoidingView seems to be the solution for you. You can set the distance between your view and the keyboard and calculate it with the height of your input. In the docs you find all properties: https://facebook.github.io/react-native/docs/keyboardavoidingview.html
You can also try using KeyboardAvoidingScrollView, then when your input is high enough you just scroll down the screen.
Here's an awesome article with great examples of keyboard avoids: https://medium.freecodecamp.org/how-to-make-your-react-native-app-respond-gracefully-when-the-keyboard-pops-up-7442c1535580
Hope it helps.
I have a render method with these components:
<View style={styles.root}>
{p.parts.map((part, index) =>
<Animated.View
key={`part${index}`}
style={[
this.draggables[index].pan.getLayout()
]}
{...this.draggables[index].panResponder.panHandlers}
>
<SphereView part={part} />
</Animated.View>
)}
</View>
And this style:
const styles = StyleSheet.create({
root: {
flexDirection: 'row'
}
});
Drag and drop is working, but the problem is that when I drag the second element, it is shown above only the first and below all others. I want the component being dragged to be above all others.
I've tried various combinations with zIndex and none worked.
How to do it?
Edit: I've now just achieved with with the "elevation" style in Android. Is it the correct approach (even for iOS)?
It's a shame that most of the PanResponder questions on SO (or at least the ones Ive seen) have no answer. You can use zIndex. Just set the zIndex to 999 or something during the drag, and then on release, set it to the original zIndex+1, so that it STAYS above the other images. If you kept all of the dragged elements at 999, they would no longer overlap after one drag.
Elevation only works on android, but zIndex works on both, and will not create a shadow/3D effect
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>