I'm trying to use the Picker component and it shows perfectly fine in iOS but nothing in Android. I've checked the comments on react native picker is not showing in android however setting the {width: 100} and {flex: 1} doesn't seem to solve the problem.
Update: The Picker is there, works when I tap on the area it's on, just not visible.
I'm using Expo to run the test builds on my iphone and android. No problem on iphone. Just android... Galaxy S8 v7.0 Nougat
Here's my code:
import React from 'react';
import {
StyleSheet,
Text,
View,
Picker,
} from 'react-native';
export default class Home extends React.Component {
constructor(props){
super(props);
this.state = {
selectedValue: 'Orange'
}
}
render() {
return (
<View style={styles.container}>
<Picker
style={styles.picker}
selectedValue={this.state.selectedValue}
onValueChange={(value) => {this.setState({selectedValue: value})}}
itemStyle={styles.pickerItem}
>
<Picker.Item label="Apple" value="Apple" />
<Picker.Item label="Orange" value="Orange" />
<Picker.Item label="Banana" value="Banana" />
<Picker.Item label="Kiwi" value="Kiwi" />
</Picker>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'column',
justifyContent: 'center',
},
picker: {
flex: 1,
},
pickerItem: {
color: '#333333'
},
});
Try To add height and width for Picker. Try Following
<Picker
style={{height:30, width:100}}
selectedValue={this.state.selectedValue}
onValueChange={(value) => {this.setState({selectedValue: value})}}
itemStyle={styles.pickerItem}>
<Picker.Item label="Apple" value="Apple" />
<Picker.Item label="Orange" value="Orange" />
<Picker.Item label="Banana" value="Banana" />
<Picker.Item label="Kiwi" value="Kiwi" />
</Picker>
Found the problem, I exported the module and imported it in my main app.js file and in there I wrapped the module in a container with alignItems: 'center'. Apparently this causes the picker to not show. See this https://github.com/facebook/react-native/issues/6110
I had the same problem and the cause was that I had set alignItems: 'center' to the parent view. This is what I wanted though so I didn't remove it. Instead I solved it by giving the picker a width of 100%.
<View style={{alignItems: "center"}}>
<Picker style={{width:"100%"}} mode="dropdown">
<Picker.Item />
</Picker>
</View>
Related
I am using react-native-flash-message https://www.npmjs.com/package/react-native-flash-message.
Everything works fine as it is easy to use them. But the problem is when i used it with the Card component (from react-native-paper), the message hides under the card. I want the message to be on the top of everything.
I tried zIndex But it doesnot work.
Here is the demo code;
import * as React from 'react';
import { View, ScrollView } from 'react-native';
import { Avatar, Button, Card, Title, Paragraph } from 'react-native-paper';
import FlashMessage from 'react-native-flash-message';
import { showMessage } from 'react-native-flash-message';
const LeftContent = (props) => <Avatar.Icon {...props} icon="folder" />;
const show = () => {
showMessage({
message: 'This is a message',
});
};
const MyComponent = () => (
<View style={{justifyContent: 'center', marginTop: 30}}>
<Card style={{ margin: 30 }} elevation={30}>
<ScrollView contentContainerStyle={{justifyContent: 'center', marginTop: 30}}>
<Card.Title
title="Card Title"
subtitle="Card Subtitle"
left={LeftContent}
/>
<Card.Content>
<Title>Card title</Title>
<Paragraph>Card content</Paragraph>
</Card.Content>
<Card.Cover source={{ uri: 'https://picsum.photos/700' }} />
<Card.Actions>
<Button onPress={() => show()}>show message</Button>
</Card.Actions>
</ScrollView>
</Card>
<FlashMessage style={{ marginTop: 20 }} position="top" />
</View>
);
export default MyComponent;
Note that this problem only occurs on android devices. On ios, it works fine.
Though i found a solution. Putting <FlashMessage style={{ marginTop: 20 }} position="top" /> inside the card component will resolve it, but i have enabled FlashMessage globally, so i want to change it globally and don't want to put it in every card component
So after some search, i found that though the react-native-flash-message is not made in that way to be rendered on top of everything like card, modals or dialog.
So one way to solve it (infact, i think this is the only way) would be to wrap the FlashMessage component in card and give it some high elevation (say 1000). Note that the elevation provided to it should by the largest among all cards used.
I'm using react-native-community/picker v1.6.1, and I'm trying to make a pre-styled picker item to avoid having the color property on each item. Below is a showcase App.js. The red picker works as expected but the yellow one renders in black instead of yellow and I don't understand why. The code is tested in an iOS emulator with a freshly generated React Native app version 0.62.2 where I've installed the picker component.
import React, {useState} from 'react';
import {SafeAreaView} from 'react-native';
import {Picker} from '#react-native-community/picker';
const YellowPickerItem = props => {
return <Picker.Item {...props} color={'yellow'} />;
};
const App = () => {
const [redValue, setRedValue] = useState(2);
const [yellowValue, setYellowValue] = useState(3);
return (
<>
<SafeAreaView style={{flex: 1}} backgroundColor={'gray'}>
<Picker selectedValue={redValue} onValueChange={setRedValue}>
<Picker.Item label={'Red 1'} value={1} key={1} color={'red'} />
<Picker.Item label={'Red 2'} value={2} key={2} color={'red'} />
<Picker.Item label={'Red 3'} value={3} key={3} color={'red'} />
<Picker.Item label={'Red 4'} value={4} key={4} color={'red'} />
</Picker>
<Picker selectedValue={yellowValue} onValueChange={setYellowValue}>
<YellowPickerItem label={'Yellow 1'} value={1} key={1} />
<YellowPickerItem label={'Yellow 2'} value={2} key={2} />
<YellowPickerItem label={'Yellow 3'} value={3} key={3} />
<YellowPickerItem label={'Yellow 4'} value={4} key={4} />
</Picker>
</SafeAreaView>
</>
);
};
export default App;
The strangest thing is that the code runs just as well if I change the YellowPickerItem component to:
const YellowPickerItem = props => {
return <SafeAreaView />;
};
It feels like I'm missing something basic about react components here, so grateful for a nudge in the right direction.
Markus
You can use itemStyle prop of the picker to styling your picker item.
I was trying to position a button on the bottom right of the screen like the picture below:
So, basically I had a Scrollview with the button inside like so:
import React, { Component } from 'react'
import { ScrollView, Text, KeyboardAvoidingView,View,TouchableOpacity } from 'react-native'
import { connect } from 'react-redux'
import { Header } from 'react-navigation';
import CreditCardList from '../Components/credit-cards/CreditCardList';
import Icon from 'react-native-vector-icons/Ionicons';
import Button from '../Components/common/Button';
// Styles
import styles from './Styles/CreditCardScreenStyle'
import CreditCardScreenStyle from './Styles/CreditCardScreenStyle';
class CreditCardScreen extends Component {
render () {
return (
<ScrollView style={styles.container}>
<CreditCardList />
<TouchableOpacity style={CreditCardScreenStyle.buttonStyle}>
<Icon name="md-add" size={30} color="#01a699" />
</TouchableOpacity>
</ScrollView>
)
}
}
My styles:
import { StyleSheet } from 'react-native'
import { ApplicationStyles } from '../../Themes/'
export default StyleSheet.create({
...ApplicationStyles.screen,
container:{
marginTop: 50,
flex: 1,
flexDirection: 'column'
},
buttonStyle:{
width: 60,
height: 60,
borderRadius: 30,
alignSelf: 'flex-end',
// backgroundColor: '#ee6e73',
position: 'absolute',
bottom: 0,
// right: 10,
}
})
The problem is that the absolute positioning does not work at all when the button is inside the ScrollView. But...If I change the code to look like this:
import CreditCardScreenStyle from './Styles/CreditCardScreenStyle';
class CreditCardScreen extends Component {
render () {
return (
<View style={styles.container}>
<ScrollView >
<CreditCardList />
</ScrollView>
<TouchableOpacity style={CreditCardScreenStyle.buttonStyle}>
<Icon name="md-add" size={30} color="#01a699" />
</TouchableOpacity>
</View>
)
}
}
Then it works !! Whaat? Why? How? I don't understand why this is happening and I would appreciate any information about it.
This might be inconvenient but is just how RN works.
Basically anything that's inside the ScrollView (in the DOM/tree) will scroll with it. Why? Because <ScrollView> is actually a wrapper over a <View> that implements touch gestures.
When you're using position: absolute on an element inside the ScrollView, it gets absolute positioning relative to its first relative parent (just like on the web). Since we're talking RN, its first relative parent is always its first parent (default positioning is relative in RN). First parent, which in this case is the View that's wrapped inside the ScrollView.
So, the only way of having it "fixed" is taking it outside (in the tree) of the ScrollView, as this is what's actually done in real projects and what I've always done.
Cheers.
i suggest to use "react-native-modal".
you can not use position: 'absolute' to make elements full size in ScrollView
but you can do it by
putting that element in modal wrapper.
below are two examples. first one doesnt work but the second one works perfectly.
first way (doesnt work):
const app = () => {
const [position, setPosition] = useState('relative')
return(
<ScrollView>
<Element style={{position: position}}/>
<Button
title="make element fixed"
onPress={()=> setPosition('absolute')}
/>
</ScrollView>
)
}
second way (works perfectly):
const app = () => {
const [isModalVisible, setIsModalVisible] = useState(false)
return(
<ScrollView>
<Modal isModalVisible={isModalVisible}>
<Element style={{width: '100%', height: '100%'}}/>
</Modal>
<Button
title="make element fixed"
onPress={()=> setIsModalVisible(true)}
/>
</ScrollView>
)
}
for me this worked:
before:
<View>
<VideoSort FromHome={true} />
<StatisticShow style={{position:'absulote'}}/>
</View>
after:
<View>
<ScrollView>
<VideoSort FromHome={false} />
</ScrollView>
<View style={{position:'relative'}}>
<StatisticShow style={{position:'absulote'}}/>
</View>
</View>
On the following code:
where is defined the: this.props referenced on the first line inside the render() function? Is there any relationship between that lowercase: props variable with the capitalized Props type? any convention here?
what implication has: ...extends React.Component<Props>?
what implication has the /* #flow */ line on the very top of the file?
https://github.com/callstack/react-native-paper/blob/e4ca933f386d7b485f6580c332f0638a55dfe2db/example/src/CardExample.js#L27
/* #flow */
import * as React from 'react';
import { Alert, ScrollView, StyleSheet } from 'react-native';
import {
Title,
Caption,
Paragraph,
Card,
Button,
withTheme,
type Theme,
} from 'react-native-paper';
type Props = {
theme: Theme,
};
class CardExample extends React.Component<Props> {
static title = 'Card';
render() {
const {
theme: {
colors: { background },
},
} = this.props;
return (
<ScrollView
style={[styles.container, { backgroundColor: background }]}
contentContainerStyle={styles.content}
>
<Card style={styles.card}>
<Card.Cover source={require('../assets/wrecked-ship.jpg')} />
<Card.Content>
<Title>Abandoned Ship</Title>
<Paragraph>
The Abandoned Ship is a wrecked ship located on Route 108 in
Hoenn, originally being a ship named the S.S. Cactus. The second
part of the ship can only be accessed by using Dive and contains
the Scanner.
</Paragraph>
</Card.Content>
</Card>
<Card style={styles.card}>
<Card.Cover source={require('../assets/forest.jpg')} />
<Card.Actions>
<Button onPress={() => {}}>Share</Button>
<Button onPress={() => {}}>Explore</Button>
</Card.Actions>
</Card>
<Card style={styles.card}>
<Card.Content>
<Title>Berries</Title>
<Caption>Omega Ruby</Caption>
<Paragraph>
Dotted around the Hoenn region, you will find loamy soil, many of
which are housing berries. Once you have picked the berries, then
you have the ability to use that loamy soil to grow your own
berries. These can be any berry and will require attention to get
the best crop.
</Paragraph>
</Card.Content>
</Card>
<Card style={styles.card}>
<Title>Just Strawberries</Title>
<Card.Cover source={require('../assets/strawberries.jpg')} />
</Card>
<Card
style={styles.card}
onPress={() => {
Alert.alert('The Chameleon is Pressed');
}}
>
<Card.Cover source={require('../assets/chameleon.jpg')} />
<Card.Content>
<Title>Pressable Chameleon</Title>
<Paragraph>
This is a pressable chameleon. If you press me, I will alert.
</Paragraph>
</Card.Content>
</Card>
<Card
style={styles.card}
onLongPress={() => {
Alert.alert('The City is Long Pressed');
}}
>
<Card.Cover source={require('../assets/city.jpg')} />
<Card.Content>
<Title>Long Pressable City</Title>
<Paragraph>
This is a long press only city. If you long press me, I will
alert.
</Paragraph>
</Card.Content>
</Card>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
content: {
padding: 4,
},
card: {
margin: 4,
},
});
export default withTheme(CardExample);
Could you give me some light on this?
References:
https://flow.org/en/docs/react/components/
Thanks!
props is defined in Component (is in base class) because you have FLOW this.props should have shape of Props )
You are extending base Component and you component can accept "Props" shape data in your example you component will accept a property theme of shape "Props".
Flow is static typing to JavaScript (https://github.com/facebook/flow || https://flow.org/)
I am trying to use KeyboardAvoidingView (also tried a few alternatives) but it either shows the keyboard over the input field or adds a huge amount of padding between the keyboard and the input field. When I stripe the page of any other content it fairs a bit better and only adds a bit of padding between the input field and the keyboard.
Demo of the issue:
http://i.imgur.com/qoYgJpC.gifv
<KeyboardAvoidingView behavior={'position'}>
{this.state.story.image_key ?
<View style={{flex: 1}}>
<Image style={styles.storyBackgroundImage} source={{uri: this.state.story.image_url}} />
<VibrancyView
style={styles.absolute}
blurType="light"
blurAmount={25}
/>
<Image style={styles.storyImage} source={{uri: this.state.story.image_url}} />
</View>
: null
}
<View style={styles.storyContainer}>
<Text style={styles.storyTitle}>{this.state.story.title}</Text>
<Text style={styles.chapterHeader} onPress={() => navigate('User', { id: this.state.story.author.id, name: this.state.story.author.name })}>Chapter 1 by {this.state.story.author.name}</Text>
<Text style={styles.storyText}>{this.state.story.content}</Text>
{this.state.story.chapters.map(function(chapter, i) {
return <ChapterComponent chapter={chapter} key={i} navigation={() => navigate('User', { id: chapter.author.id, name: chapter.author.name })}></ChapterComponent>
})}
<WritingComponent></WritingComponent>
</View>
</KeyboardAvoidingView>
WritingComponent
import React from 'react';
import {
AppRegistry,
TextInput
} from 'react-native';
export default class WritingComponent extends React.Component {
constructor(props) {
super(props);
this.state = { text: '' };
}
render() {
return (
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
multiline={true}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
)
}
}
AppRegistry.registerComponent('WritingComponent', () => WritingComponent);
Link to code
I think the problem is the scroll view, <ScrollView style={{flex: 1}}> should be contained within your KeyboardAvoidingView Since you want this scrolling container also be resized when keyboard comes up...
set keyboardVerticalOffset="80" along with keyboardAvoidingView.
Increase/decrease 80 according to the width of your component