I have updated to Expo SDK 42 in my react-native app, and I am running into one issue one one particular screen that makes use of KeyboardAwareScrollView. On iOS everything is fine. But on Android all I see is a white screen below the header for the code below. Note that if I remove <KeyboardAwareScrollView> altogether, the content again shows up in Android.
Notice I have enableOnAndroid set to true on KeyboardAwareScrollView.
<KeyboardAwareScrollView
enableOnAndroid={true}
enableAutomaticScroll={(Platform.OS === 'ios')}
>
Here is the full code block:
render() {
return (
<TouchableWithoutFeedback
onPress={Keyboard.dismiss}
>
<KeyboardAwareScrollView
enableOnAndroid={true}
enableAutomaticScroll={(Platform.OS === 'ios')}
>
<View style={styles.layout.footerPadding}>
<Image source={require('../assets/images/thestaff.jpg')} style={{
width: '100%',
height: winSize.width * 0.5,
}} />
<View style={{
...styles.forms.sectionContainer,
borderTopWidth: 10,
borderTopColor: styles.colors.primary,
}}>
<View style={{
...styles.forms.fieldContainer,
flexDirection: 'column'
}}>
<Text style={{
...styles.forms.fieldLabel,
...styles.layout.fullWidth,
}}>Please reach out with any concerns that you may have.</Text>
<View style={{
...styles.layout.flexRowJustifyEnd,
...styles.layout.fullWidth,
}}>
<Text style={{
...styles.forms.fieldLabel,
marginTop: 10,
width: 190
}}>-The Office Staff</Text>
</View>
<TextInput
style={{
...styles.layout.fullWidth,
marginTop: 30,
}}
multiline={true}
editable={true}
maxLength={1500}
placeholder="Enter a message"
onChangeText={(value) => {
this.setState({ message: value })
}}
value={this.state.message}
/>
</View>
</View>
<View style={styles.forms.submitButton}>
<GradientButton
indicatorColor={styles.colors.textInverse}
onPress={this.handleSendMessage}
isLoading={false}
value="SEND"
/>
</View>
</View>
</KeyboardAwareScrollView>
</TouchableWithoutFeedback>
);
}
Any ideas on what I need to change would be helpful.
Add styling to the touchable component and keyboardAwareScrollview component.
<TouchableWithoutFeedback
style={{ flex: 1 }}
onPress={Keyboard.dismiss}
>
<KeyboardAwareScrollView
style={{ flex: 1 }}
enableOnAndroid={true}
enableAutomaticScroll={(Platform.OS === 'ios')}
>
Related
I was making an app and added text on HomeScreen. I am getting the text in Web but am not able to get it in Android and IOS. This is the Code:
render(){
let pulse = <Image source={require('../pulse.png')} style={styles.pulse} />
return (
<SafeAreaView style={styles.container}>
<View>
<StatusBar barStyle="dark-content" />
<View style={{ flex: 0.4, resizeMode: 'contain' }}>
<Text style={styles.appName}>L{pulse}blood</Text>
</View>
</View>
</SafeAreaView>
}
These are the styles
container: {
flex: 1,
backgroundColor: 'white',
},
appName: {
alignSelf: 'center',
fontFamily: 'oswald',
fontSize: 50,
color: 'black',
height: '100%'
}
You need to remove the flex prop of the child view. Change
<View style={{ flex: 0.4, resizeMode: 'contain' }}>
<Text style={styles.appName}>L{pulse}blood</Text>
</View>
to
<View style={{ resizeMode: 'contain' }}>
<Text style={styles.appName}>L{pulse}blood</Text>
</View>
Everyone.
I need your help.
I made one app with react native expo cli.
But one issue occurred.
I used the ScrollView for horizontal pagination.
*<SafeAreaView>
<ScrollView
snapToInterval={wp("100%")}
horizontal
pagingEnabled
nestedScrollEnabled
decelerationRate="fast"
>
{[...Array(this.state.pageCount)].map((num, index) => {
return (
<View
key={"view" + index}
style={{
width: wp("100%"),
height: "100%",
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
alignContent: "center",
justifyContent: "center",
}}
>
{this.state.categories
.slice(index * 6, index * 6 + 6)
.map((item, key) => (
<TouchableOpacity
key={"touch" + key}
style={styles.itemStyle}
onPress={() => this.openModal(item)}
onLongPress={() => this.selectItem(item)}
>
<Image
source={{ uri: item.Foto }}
style={{ height: 120, width: "90%" }}
resizeMode="cover"
/>
<Text style={{ fontSize: 18 }}>{item.Precio}</Text>
<Text style={{ fontSize: 12 }}>{item.Gemas}</Text>
</TouchableOpacity>
))}
</View>
);
})}
</ScrollView>
</SafeAreaView>*
But the pagination only works on Android Phone and doesn't work on iPhone.
Please help me.
Your <ScrollView> should have style flex: 1, to allow the view fit the screen size.
The width of the Views inside the Scroll should have a numerical value. A width of 100% inside a scrollview is undefined. Your approach should be related to the dimension of the screen.
// import dimensions lib
import Dimensions from 'react-native';
...
...
...
// capture the width of the screen
const screenWidth = Dimensions.get('screen').width;
...
...
...
{[...Array(this.state.pageCount)].map((num, index) => {
return (
<View
key={"view" + index}
style={{
width: screenWidth,
height: "100%",
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
alignContent: "center",
justifyContent: "center",
}}
>
{this.state.categories
.slice(index * 6, index * 6 + 6)
.map((item, key) => (
<TouchableOpacity
key={"touch" + key}
style={styles.itemStyle}
onPress={() => this.openModal(item)}
onLongPress={() => this.selectItem(item)}
>
<Image
source={{ uri: item.Foto }}
style={{ height: 120, width: "90%" }}
resizeMode="cover"
/>
<Text style={{ fontSize: 18 }}>{item.Precio}</Text>
<Text style={{ fontSize: 12 }}>{item.Gemas}</Text>
</TouchableOpacity>
))}
</View>
);
})}
This question already has answers here:
TextInput weird behaviour in React-Native
(2 answers)
Closed 3 years ago.
I have used TouchableOpacity as my submit button, after filling the form(Login/Registration/...) when I click on submit button(TouchableOpacity), the keyboard hides (if open), and then I need to press again on submit button and then the onPress method gets called.
What I want to achieve is if I click on submit button, the onPress() method should call, regardless of the keyboard is open or not. I have to click two times to submit the form which does not look good.
Also, I have not tested this behaviour on IOS, android only.
EDIT:1
Login Screen Code =>
<KeyboardAvoidingView>
<ScrollView>
<View style={styles.container}>
<View style={styles.container_one}>
<Image
style={{ height: 100, marginTop: 40 }}
source={require("../images/logo.png")}
/>
</View>
<View style={styles.container_three}>
<View>
<View style={styles.container_two}>
<Text style={styles.text_style_two}>Login</Text>
</View>
<View>
<Text style={styles.text_style_three}>
Please enter mobile number
</Text>
<TextInput
style={styles.text_input_1}
autoCapitalize="none"
keyboardType="numeric"
onChangeText={text => {
this.setState({
username: text
});
}}
value={this.state.username}
/>
</View>
<View>
<Text style={styles.text_style_three}>
Please enter your password
</Text>
<TextInput
style={styles.text_input_1}
secureTextEntry={true}
autoCapitalize="none"
onChangeText={text => {
this.setState({
password: text
});
}}
value={this.state.password}
/>
</View>
<View
style={{
width: screenWidth / 1.3,
flexDirection: "row",
justifyContent: "center"
}}
>
<View>
<TouchableOpacity
style={styles.button_1}
onPress={() => {
if (this.state.username == "") {
alert("Username can not be blank");
} else if (this.state.password == "") {
alert("Password can not be blank");
} else {
this.submitLogin(
this.state.username,
this.state.password
);
}
}}
>
<Text style={CommonStyles.buttonText}>Login</Text>
</TouchableOpacity>
</View>
</View>
</View>
</View>
<View style={{ alignItems: "center" }}>
<View style={{ marginBottom: 10 }}>
<Text style={{ fontSize: 20 }}>-OR-</Text>
</View>
<View style={{ marginBottom: 10 }}>
<TouchableOpacity
onPress={() => {
this.props.navigation.navigate("Registration");
}}
>
<Text style={styles.text_style_one}>Sign up here</Text>
</TouchableOpacity>
</View>
</View>
<View style={{ alignItems: "center" }}>
<View style={{ marginBottom: 10 }}></View>
<View style={{ marginBottom: 10 }}>
<TouchableOpacity
onPress={() => {
this.props.navigation.navigate("ForgotPassword");
}}
>
<Text style={styles.text_style_five}>forgot password?/Text>
</TouchableOpacity>
</View>
</View>
</View>
</ScrollView>
</KeyboardAvoidingView>
Just add keyboardShouldPersistTaps={'handled'} to your ScrollView
<ScrollView keyboardShouldPersistTaps={'handled'}>
......
..............
</ScrollView>
I use react-native-vector-icons.
Click the input
Keyboard goes up
When pressing the icon, icon doesn't trigger, the keyboard will go down first rather than the onpress method icon triggers while having the keyboard is on
Expected Result would like a live chat, while keyboard is up submit icon will always trigger.
I tried to enwrap it in scrollview with keyboardshouldpersisttaps and it doesn't work.
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : null}
style={{ flex: 1 }}
keyboardVerticalOffset={64}
>
<View style={styles.slide} key={i}>
<TouchableHighlight
style={styles.video}
onPress={this.handleDoubleTap}
onLongPress={this.handlePlayAndPause}
>
<ViewportAwareVideo
key={i}
source={{ uri: firstVideoUri }}
shouldPlay={this.state.shouldPlay}
isLooping
preTriggerRatio={-0.4} // default is 0
retainOnceInViewport={false} // default is false
style={styles.video}
onPlaybackStatusUpdate={this._onPlaybackStatusUpdate}
progressUpdateIntervalMillis={1000}
resizeMode='contain'
innerRef={ref => (this._videoRef = ref)}
onViewportEnter={() => {
this.setState({ shouldPlay: true });
}}
onViewportLeave={() => {
this.setState({ shouldPlay: false });
}}
/>
</TouchableHighlight>
{this.state.shouldPlay ? null : (
<TouchableHighlight
onPress={this.handlePlayAndPause}
style={styles.pauseBtn}
>
<IconComponent name='play-circle' size={50} color='black' />
</TouchableHighlight>
)}
<CopilotStep
name='swipeUp'
text='Swipe up to view next video'
order={5}
>
<WalkthroughableView style={styles.topSection}>
<Text style={styles.imageHeadingText}>{product.name}</Text>
{product.short_description === '' ? null : (
<HTML
html={product.short_description}
imagesMaxWidth={Dimensions.get('window').width}
containerStyle={styles.imageDescText}
baseFontStyle={styles.htmlStyle}
/>
)}
<CopilotStep
name='swipeRight'
text='Swipe right to view product details'
order={6}
>
<WalkthroughableView
style={{
flexDirection: 'row',
flexWrap: 'wrap',
paddingHorizontal: 20,
paddingVertical: 5
}}
>
{product.tags.map((value, index) => {
return (
<Text key={index} style={styles.tagText}>
{value.name.charAt(0) === '#'
? value.name
: '#' + value.name}
</Text>
);
})}
</WalkthroughableView>
</CopilotStep>
{product.total_sales > 0 ? (
<View
style={{
flexDirection: 'row',
flexWrap: 'wrap',
paddingHorizontal: 20,
paddingVertical: 5
}}
>
<Text style={styles.totalSales}>
{product.total_sales +
(product.total_sales > 100
? '+ bought'
: ' bought in the last 24 hours')}
</Text>
</View>
) : null}
</WalkthroughableView>
</CopilotStep>
<View style={styles.bottomSection}>
<View style={{ flex: 1, justifyContent: 'flex-end', height: 30 }}>
{this.state.messages.map((message, index) => (
<React.Fragment key={index}>
<View
key={index}
style={{
flexDirection: 'row',
alignItems: 'center',
marginHorizontal: 5,
marginVertical: 5,
paddingLeft: 10,
height: 20
}}
>
<Image
style={{ width: 20, height: 20, borderRadius: 20 / 2 }}
source={{ uri: 'https://picsum.photos/20/20' }}
/>
<Text
style={{
fontFamily: Constants.fontHeader,
marginHorizontal: 5,
color: '#007AFF'
}}
>
{message.user.name}
</Text>
<Text
style={{
fontFamily: Constants.fontHeader,
marginHorizontal: 5,
color: 'white'
}}
>
{message.text}
</Text>
</View>
</React.Fragment>
))}
</View>
<CopilotStep
name='chatOnFeed'
text='Click here to chat on video feed'
order={7}
>
<WalkthroughableTextInput
style={{
// position: 'absolute',
// bottom: 0,
// left: 0,
fontFamily: Constants.fontFamily,
marginBottom: 110,
marginHorizontal: 5,
marginVertical: 5,
paddingRight: 35,
paddingLeft: 20,
height: 35,
width: width - 60,
backgroundColor: 'white',
borderRadius: 25
}}
onChangeText={messageText => this.setState({ messageText })}
value={this.state.messageText}
placeholder='Share your thoughts'
placeholderTextColor='#9B9B9B'
/>
</CopilotStep>
<IconComponent
style={{ position: 'absolute', bottom: 115, right: 10 }}
name='arrow-right'
size={25}
color='black'
onPress={product => this.sendMessage(product)}
/>
</View>
<View style={styles.iconBar}>
<CopilotStep
name='productDetail'
text='Click here to got to product details'
order={8}
>
<WalkthroughableText>
<IconComponent
style={styles.iconBarIcon}
name='shopping-cart'
size={iconSize}
color='white'
onPress={() => {
this.props.onViewProductScreen({ product });
this.setState({ shouldPlay: false });
}}
/>
</WalkthroughableText>
</CopilotStep>
<Text style={styles.iconBarText}>Shop</Text>
<CopilotStep
name='like'
text='Click here to like this product'
order={9}
>
<WalkthroughableText>
<Entypo
style={styles.iconBarIcon}
name='heart'
size={30}
color={this.state.isInWishList ? 'red' : 'white'}
onPress={() => {
this.state.isInWishList
? this.props.removeWishListItem(product)
: this.props.addWishListItem(product);
this.setState(prevState => ({
isInWishList: !prevState.isInWishList
}));
}}
/>
</WalkthroughableText>
</CopilotStep>
<Text style={styles.iconBarText}>Like</Text>
<CopilotStep
name='share'
text='Click here to share this product'
order={10}
>
<WalkthroughableText>
<IconComponent
style={styles.iconBarIcon}
name='share'
size={iconSize}
color='white'
onPress={this.onShare}
/>
</WalkthroughableText>
</CopilotStep>
<Text style={styles.iconBarText}>Share</Text>
<CopilotStep
name='fullChat'
text='Click here to view full chat'
order={11}
>
<WalkthroughableText>
<IconComponent
style={[styles.iconBarIcon, { paddingTop: 4 }]}
name='message-circle'
size={iconSize}
color='white'
onPress={product => this.sendChat(product)}
/>
</WalkthroughableText>
</CopilotStep>
</View>
</View>
</KeyboardAvoidingView>
);
You can see my problem is on IconComponent after the WalkthroughableTextInput
If you are using NativeBase component use it like this
<Content keyboardShouldPersistTaps={'handled'}>
...
</Content>
For ReactNative <ScrollView/>
<ScrollView keyboardShouldPersistTaps={'handled'}>
...
</ScrollView>
I have used Content to achieve the vertical scrolling and tried using ScrollView as well. But nothing works with Card component in native-base. This behavior was shown when testing in an Android emulator.
Following is my working,
render() {
return (
<Container>
<Header style={{backgroundColor: Colors.headerBackground, justifyContent: 'center', marginTop: '4%'}}>
<Left>
<Button transparent onPress={this.handleBackButtonClick} small={true}>
<Icon name='arrow-back' size={30} color={Colors.textWhite}/>
</Button>
</Left>
<Body>
<Title style={{
fontSize: 20,
fontWeight: '200'
}}>Events</Title>
</Body>
</Header>
<Content>
{ (this.state.events).map(event => { return (
<Card key={event.title} style={{ marginTop:'2%', marginLeft:'2%', marginRight:'2%', marginBottom:'2%'}}>
<CardItem>
<Image source={{uri:event.uri}}
style={{height:200, width: null, flex:1}}/>
</CardItem>
<CardItem>
<Left>
<View style={{height: '50%'}}>
<Text style={{color: Colors.calenderMonth, fontSize: 15}}>Jun</Text>
<Text style={{fontSize: 15}}>15</Text>
</View>
</Left>
<Body style={{alignSelf: 'flex-start', marginLeft: '-50%'}}>
<Text style={{fontSize: 20, fontWeight: 'bold'}}>{event.title}</Text>
<Text note>{event.desc}</Text>
</Body>
</CardItem>
</Card>
) } ) }
</Content>
</Container>
);
}
Any ideas? Thanks
Set flexGrow: 1 to contentContainerStyle prop of the Content component:
<Content contentContainerStyle={{ flexGrow: 1 }}>
This worked for me after many hours of struggling with the issue.
I had the same issue with one of my project. I realize that the <Card> wasn't scrolling even after i place it in a <ScrollView> because it was within the <Container>.
I solved it by creating a separate Component with the <Card> within the <ScrollView> and import it.
Example:
render() {
return (
<ScrollView>
<Card>
<CardItem>
</CardItem>
</Card>
</ScrollView>
);
}
Import it:
render() {
return (
<Container>
<Content>
<ScrollingCardExample />
</Content>
</Container>
);
}
Use <ScrollView> instead of <Content> and make sure u have enough contents to test scrolling.
tried your code with some data. Working fine for me.
import React, { Component } from 'react';
import { Image } from "react-native";
import { Container, Header, Left, Body, Button, Icon, Title, Content, Card, CardItem, View, Text } from 'native-base';
export default class App extends Component {
state = { events: [1, 2, 3, 4, 5] }
render() {
return (
<Container>
<Header style={{ justifyContent: 'center', marginTop: '4%' }}>
<Left>
<Button transparent onPress={this.handleBackButtonClick} small={true}>
<Icon name='arrow-back' size={30} color="white" />
</Button>
</Left>
<Body>
<Title style={{
fontSize: 20,
fontWeight: '200'
}}>Events</Title>
</Body>
</Header>
<Content>
{(this.state.events).map(event => {
return (
<Card key={event} style={{ marginTop: '2%', marginLeft: '2%', marginRight: '2%', marginBottom: '2%' }}>
<CardItem>
<Image source={{ uri: "https://nativebase.io/assets/img/front-page-icon.png" }}
style={{ height: 200, width: null, flex: 1 }} />
</CardItem>
<CardItem>
<Left>
<View style={{ height: '50%' }}>
<Text style={{ fontSize: 15 }}>Jun</Text>
<Text style={{ fontSize: 15 }}>15</Text>
</View>
</Left>
<Body style={{ alignSelf: 'flex-start', marginLeft: '-50%' }}>
<Text style={{ fontSize: 20, fontWeight: 'bold' }}>Title</Text>
<Text note>Description</Text>
</Body>
</CardItem>
</Card>
)
})}
</Content>
</Container>
);
}
}
Gif