I animate my view up 120 pixels when the keyboard opens for a Modal I have. When the keyboard closes, the view returns 120 pixels down. The problem is, the area that goes off screen at the top, when it gets animated back, the view is slightly smaller, and it gets slightly smaller each time, Here is the code - I will put a comment to show the view that is shrinking:
<Animated.View
style={{
paddingTop: 5,
paddingBottom: 10,
paddingLeft: 10,
paddingRight: 10,
marginTop: this.state.yPosition,
marginBottom: this.state.yPositionPositive,
flex: 1,
marginLeft: (Dimensions.get('window').width - 300) / 4,
backgroundColor: 'rgba(0,0,0,0.8)',
width: 300,
borderRadius: 4,
borderWidth: 0,
}}>
<View style={{ flexDirection: 'column', justifyContent: 'space-between', flex: 1 }}>
<View style={{height: 126, backgroundColor: 'blue', alignItems: 'stretch'}}>
<ScrollView contentContainerStyle={{flexGrow:1}} style={{flexDirection: 'column', backgroundColor: '#e6fffe'}}>
<View style={{height: 90, backgroundColor: 'red', flexDirection: 'row', justifyContent: 'center', alignItems: 'center', paddingTop: 5, paddingBottom: 5, borderBottomColor: '#6de3dc', borderBottomWidth: 0}}>
<View style={{justifyContent: 'center', alignItems: 'center', flex: 0.5}}>
<View style={{flexDirection: 'column', justifyContent: 'space-between'}}>
<Image
source={require('../assets/billythekid2.jpg')}
style={{height: 60, width: 60, marginTop: Platform.OS === 'ios' ? 10 : 10, borderColor: '#6de3dc', borderWidth: 2, borderRadius: 30}}
/>
<View style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center', marginTop: 5}}>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
</View>
</View>
</View>
<View style={{flexDirection: 'column', backgroundColor: '#e6fffe', marginTop: Platform.OS === 'ios' ? 10 : 10, flex: 0.5}}>
<View style={{flexDirection: 'row', flex: 0.5}}>
<View style={{flex: 0, alignSelf: 'center'}}>
<Text style={{fontSize: 16, fontWeight: '700'}}>
eamon.white
</Text>
</View>
</View>
</View>
</View>
<View style={{flex: 0, marginBottom: 5, backgroundColor: '#e6fffe'}}>
<Text
style={{
width: 280,
flex: 0,
backgroundColor: '#e6fffe',
paddingLeft: 5,
borderWidth: 0,
borderRadius: 4,
color: '#000',
fontSize: 14,
}}>
{this.state.messageFromSender}
</Text>
</View>
</ScrollView>
</View>
<View style={{flex: 1}} onLayout={(event) => {
this.setState({height: event.nativeEvent.layout.height});
}}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={{ flexDirection: 'column', flex: 1 }}>
<Text
style={{
flex: 0,
width: Dimensions.get('window').width,
color: 'white',
fontWeight: '700',
marginTop: 5,
marginBottom: 5
}}>
Date(s) Needed:
</Text>
{this.showCalendar()}
</View>
</TouchableWithoutFeedback>
<View style={{ flex: 0, marginBottom: 10, justifyContent: 'center', flexDirection: 'column', marginTop: 0 }}>
<TextInput
style={{
width: 280,
borderColor: 'gray',
borderWidth: 1,
backgroundColor: '#ffffff',
paddingLeft: 5,
borderRadius: 4,
height: this.state.height - 313
}}
onChangeText={text => this.setState({ message: text })}
value={this.state.message}
multiline={true}
numberOfLines={2}
onFocus={this.animateUp}
placeholder='Type a message...'
/>
</View>
</View>
<View style={{ flex: 0.1, borderRadius: 4, borderWidth: 0, marginBottom: 10 }}>
<TouchableOpacity
activeOpacity={1}
style={{
backgroundColor: this.state.rentButtonBackground,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: 280,
borderRadius: 4,
borderWidth: 0,
}}
onPress={() => {
}}>
<Text
style={{
backgroundColor: this.state.rentButtonBackground,
textAlign: 'center',
color: 'white',
fontWeight: '900',
fontSize: 18,
borderRadius: 4,
borderWidth: 0,
}}>
RESPOND
</Text>
</TouchableOpacity>
</View>
<View style={{ flex: 0.1, borderRadius: 4, borderWidth: 0, marginBottom: 10 }}>
<TouchableOpacity
activeOpacity={1}
style={{
backgroundColor: this.state.rentButtonBackground,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: 280,
borderRadius: 4,
borderWidth: 0,
}}
onPress={() => {
}}>
<Text
style={{
backgroundColor: this.state.rentButtonBackground,
textAlign: 'center',
color: 'white',
fontWeight: '900',
fontSize: 18,
borderRadius: 4,
borderWidth: 0,
}}>
ACCEPT
</Text>
</TouchableOpacity>
</View>
<View style={{ flex: 0.1, borderRadius: 4, borderWidth: 0 }}>
<TouchableOpacity
activeOpacity={1}
style={{
backgroundColor: this.state.rentButtonBackground,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: 280,
borderRadius: 4,
borderWidth: 0,
}}
onPress={() => {
}}>
<Text
style={{
backgroundColor: this.state.rentButtonBackground,
textAlign: 'center',
color: 'white',
fontWeight: '900',
fontSize: 18,
borderRadius: 4,
borderWidth: 0,
}}>
DECLINE
</Text>
</TouchableOpacity>
</View>
</View>
</Animated.View>
Animations:
animateUp = () => {
Animated.parallel([
Animated.timing(this.state.yPosition, {
toValue: -120,
duration: 300,
}),
Animated.timing(this.state.yPositionPositive, {
toValue: 120,
duration: 300,
})
]).start();
}
Animated.parallel([
Animated.timing(this.state.yPosition, {
toValue: 0,
duration: 1,
}),
Animated.timing(this.state.yPositionPositive, {
toValue: 0,
duration: 1,
})
]).start()
It starts out like this:
Each time the keyboard opens and closes, and the animation happens, pushing the top of the modal off the screen, the ScrollView shrinks a little - until it ends up looking like this:
Any suggestions would be great.
If you need to animate a view when the keyboard opens, use KeyboardAvoidingView:
https://facebook.github.io/react-native/docs/keyboardavoidingview
Related
I have a simple textbox to which i have given an outline. However, If you look closely you will see that the border and the border outline dont match. The white color of the View extends out of the border outline as well. How can I fix this?
export const AddressTextBox: React.FunctionComponent<AddressTextBoxProps> = ({
placeName,
}) => {
return (
<View style={styles.textBox}>
<Text style={styles.text}>{placeName}</Text>
</View>
);
};
export const styles = StyleSheet.create({
textBox: {
backgroundColor: 'white',
height: moderateScale(50),
width: '70%',
marginTop: moderateScale(40),
alignSelf: 'center',
borderRadius: moderateScale(20),
borderColor: '#383838',
borderWidth: 0.3,
alignItems: 'center',
flexDirection: 'row',
},
text: {
fontSize: moderateScale(13),
flex: 1,
marginHorizontal: 10,
textAlign: 'center',
},
});
Edit:
The problem doesn't exist in iOS simulator but does occur in Android phones.
I try with this and without moderateScale and it works fine
<View style={{ flex: 1, backgroundColor: 'pink' }}>
<View
style={{
backgroundColor: 'white',
height: 50,
width: '70%',
marginTop: 40,
alignSelf: 'center',
borderRadius: 20,
borderBottomColor: 'red',
borderTopColor: 'red',
borderRightColor: 'red',
borderLeftColor: 'red',
borderWidth: 0.3,
alignItems: 'center',
flexDirection: 'row'
}}>
<Text
style={{
fontSize: 13,
flex: 1,
marginHorizontal: 10,
textAlign: 'center'
}}>
{'vergaminol'}
</Text>
</View>
</View>
I have put an icon with the text box but its not showing in a same line,there is problem in alignment.I have tried many solutions . I am using flex Box.Any help would be appreciated.I set parent view to column and set child view in which icon and text box is going to show to row to align it in the same row but its not aligning it proper.i don't knows where the problem is occurring.
import {
View,
ImageBackground,
Text,
StyleSheet,
Image,
KeyboardAvoidingView,
TextInput,
TouchableOpacity
} from "react-native";
import React from "react";
import { AntDesign } from "#expo/vector-icons";
import { Feather } from "#expo/vector-icons";
export default function Login() {
return (
<View>
<ImageBackground
style={styles.backgroundImage}
source={require("../assets/bg_image.png")}
>
<View style={styles.container}>
<Image source={require("../assets/ic_logo.png")} />
<Text style={styles.welcomeText}>Welcome to SMACC</Text>
<KeyboardAvoidingView behavior="position">
<View style={styles.loginInfo}>
<View style={styles.inputField}>
<Text>User Name</Text>
<View style={styles.inputText}>
<AntDesign style={styles.icon} name="user" />
<TextInput placeholder="Enter User Name Here" />
</View>
</View>
<View
style={{
borderBottomColor: "#999999",
borderBottomWidth: 1
// marginTop: 12.5
}}
/>
<View style={styles.inputField}>
<Text>Password</Text>
<View style={styles.inputText}>
<Feather style={styles.icon} name="lock" />
<TextInput placeholder="Enter Password Here" />
</View>
</View>
<View style={styles.loginButton}>
<TouchableOpacity>
<Text style={styles.loginButtonText}>Login</Text>
</TouchableOpacity>
</View>
</View>
</KeyboardAvoidingView>
<View>
<Text style={styles.forgetPasswordLink}>Foget Password ?</Text>
</View>
</View>
</ImageBackground>
</View>
);
}
let styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "column",
justifyContent: "center",
alignItems: "center"
},
backgroundImage: {
width: "100%",
height: "100%"
},
welcomeText: {
paddingVertical: 20,
fontSize: 15,
fontFamily: "Roboto-Medium"
},
loginInfo: {
backgroundColor: "#FFFFFF",
shadowColor: "#000",
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.8,
shadowRadius: 2,
elevation: 5,
borderRadius: 5,
height: 165,
width: 253
},
inputField: {
flex: 1,
paddingTop: 10,
marginLeft: 20,
//fontSize: 10,
color: "#999999",
fontFamily: "Roboto-Medium"
},
inputText: {
flexDirection: "row",
//flex:0.5,
//marginLeft: 20,
fontSize: 12,
color: "#000000",
fontFamily: "Roboto-Medium"
},
loginButton: {
flex: 0.6,
alignItems: "center",
justifyContent: "center",
backgroundColor: "#1968B3",
borderBottomLeftRadius: 5,
borderBottomRightRadius: 5
},
loginButtonText: {
color: "#FFFFFF",
fontFamily: "Roboto-Medium",
fontSize: 12
},
forgetPasswordLink: {
paddingTop: 10,
fontFamily: "Roboto-Medium",
fontSize: 12,
color: "#333333"
},
icon: {
paddingRight: 5
//paddingTop:7
}
});
Try this as inputText style
inputText: {
flexDirection: 'row',
justifyContent:'space-between',
alignItems:'center',
fontSize: 12,
color: '#000000',
fontFamily: 'Roboto-Medium',
},
feel free for doubts..
Can you try adding display: 'flex' to the css and see if that works?
inputText: {
display: 'flex',
flexDirection: "row",
//flex:0.5,
//marginLeft: 20,
fontSize: 12,
color: "#000000",
fontFamily: "Roboto-Medium"
}
I'm trying to imitate the image.
I'm having a problem with the button with the like in the middle I can not imitate it.
Since I read it seems that native react on android has a problem with overflow.
I thought you could use a:
marginTop: -25
but it does not seem to solve the problem.
Some advice?
Link expo: https://snack.expo.io/Hk1yUyzB7
Code:
import React, { Component } from 'react';
import { View, StyleSheet, Image, Text } from 'react-native';
//import ViewOverflow from 'react-native-view-overflow';
export default class App extends Component {
render() {
var account = (
<View>
<View
style={{
paddingTop: 20,
paddingLeft: 20,
flexDirection: 'row',
}}>
<Image
style={{ width: 50, height: 50, borderRadius: 25 }}
source={{
uri:
'http://www1.pictures.zimbio.com/bg/Number+Four+World+Premiere+h5-FoI0M8-gl.jpg',
}}
/>
<View
style={{
paddingLeft: 20,
}}>
<Text>Yulia James</Text>
<Text
style={{
color: '#ccc',
}}>
6 hrs ยท IIT London
</Text>
</View>
</View>
<Text
style={{
paddingTop: 20,
paddingLeft: 20,
paddingBottom: 20,
}}>
Making everyday worth it :)
</Text>
<View
style={{
paddingBottom: 20,
}}>
<Image
style={{
width: '100%',
height: 200,
}}
source={{
uri:
'http://www.wordzz.com/wp-content/uploads/2016/11/Night-Ratri.jpg',
}}
/>
</View>
</View>
);
var com = (
<View
style={{
backgroundColor: 'rgba(230,230,230,0.8)',
//height: 40,
alignItems: 'center',
//justifyContent: 'center',
padding: 5,
flex: 1,
}}>
<Text
style={{
color: '#ccc',
fontSize: 18,
}}>
Comment
</Text>
</View>
);
return (
<View
style={{
flex: 1,
backgroundColor: '#e7eff0',
}}>
<View
style={{
backgroundColor: 'rgba(255,255,255,0.8)',
marginTop: 50,
borderTopWidth: 1,
borderBottomWidth: 1,
borderColor: '#e7e7e7',
}}>
{account}
<View
style={{
backgroundColor: '#fff',
borderTopWidth: 1,
borderColor: '#ccc',
//alignItems: 'center',
//justifyContent: 'center',
}}>
<View style={styles.container2}>
{com}
<View
style={{
//backgroundColor: '#000',
borderRadius: 40,
height: 80,
width: 80,
alignItems: 'center',
justifyContent: 'center',
borderColor: '#ccc',
borderWidth: 1,
}}>
<Image
style={{
//resizeMode: 'cover',
height: 40,
width: 40,
}}
source={{
uri: 'http://i.imgur.com/k5jMsaH.gif',
}}
/>
</View>
{com}
</View>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container2: {
flexDirection: 'row',
},
});
I have a MapView, with a text above it:
<View style={{ height: 310, alignItems: 'center', marginBottom: 10 }}>
<MapView style={ { height: 300, width: 350, } } initialRegion= .. >
<View style={{ height: 60, backgroundColor: 'rgba(255,255,255,0.7)' , flexDirection: 'column'}}>
<View style={{flexDirection: 'row'}} >
<Text style={{ fontSize: 20, color: 'black' }}> {this.state.title} </Text>
</View>
<View style={{flexDirection: 'row'}}>
<Text style={{ marginTop: 5, fontSize: 15, color: 'black', marginRight: 13}}> {this.state.startLoc.name} </Text>
<Text style={{ marginTop: 5, fontSize: 15, backgroundColor: 'transparent', color: 'black' }}> {buildTimeString(new Date(this.state.startDate))} </Text>
<Text style={{ marginTop: 5, fontSize: 15, backgroundColor: 'transparent', color: 'black' }}> {getDistanceOneToOne(this.state.startLoc, this.state.destinationLoc).distance} </Text>
</View>
</View>
..
</View>
Sometimes it displays the two texts (lines) right, but most of the times it displays them wrong (bot above each other):
What could be the issue?
I'm trying to have a popup dialog (created as a component with position: 'absolute') and to close it when user clicks outside of the popup.
I'm new to React Native so other things I did might be wrong, forgive me for that :)
This is a screenshot of the popup when it is open
This is some of the code:
From the Popup component:
render() {
if (!this.props.open) {
return <View />
}
return (
<View style={styles.container}>
<View style={styles.popupStyle}>
<View style={{flex:1, justifyContent: 'center', marginRight: 10}}>
<View style={styles.amountEnterStyle}>
<TextInput
keyboardType={'numeric'}
underlineColorAndroid='transparent'
autoCorrect={false}
style={styles.textInputStyle}
value={this.state.amount}
onChangeText={this._onAmountEnter.bind(this)} />
<Text style={styles.currencyTextStyle}>NIS</Text>
</View>
<View style={styles.separatorStyle} />
<View style={styles.categorySectionStyle}>
{this._renderCategoryDropdown()}
</View>
</View>
<View style={{justifyContent: 'center'}}>
<TouchableWithoutFeedback
onPress={this._onAddPaymentClicked.bind(this)} >
<View style={{width: 110, height:100, backgroundColor: "#ff0000"}} />
</TouchableWithoutFeedback>
</View>
</View>
</View>
);
const styles = StyleSheet.create({
container: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
width: undefined,
height: undefined,
justifyContent: 'center',
alignItems: 'center',
},
amountEnterStyle: {
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row'
},
textInputStyle: {
width: 100,
fontSize: 50,
fontWeight: 'bold',
height: 65,
flex: 1,
marginTop: -20,
paddingBottom: 0,
marginBottom: 0,
marginLeft:10,
textAlignVertical: 'center'
},
currencyTextStyle: {
fontSize: 50,
color: '#c0c0c0',
marginTop: -20,
textAlignVertical: 'center'
},
separatorStyle: {
height: 2,
marginTop: 0,
backgroundColor: '#c0c0c0',
},
categorySectionStyle: {
justifyContent: 'flex-start',
flexDirection: 'row',
alignItems: 'flex-start',
marginTop: 8
},
categoryColorDotStyle: {
width: 20,
height: 20,
borderRadius: 100/2,
marginLeft: 10,
marginTop: 5,
},
categoryTextStyle: {
fontSize: 24,
marginHorizontal: 4,
color: '#c0c0c0',
marginLeft: 10,
paddingRight: 10,
marginTop: -3
},
popupStyle: {
width: Dimensions.get('window').width - 60,
flexDirection: 'row',
justifyContent: 'space-between',
height: 150,
paddingRight:10,
paddingLeft:10,
borderRadius: 2,
margin: 20,
padding: 10,
opacity: 1,
borderRadius: 10,
backgroundColor: '#ffffff'
},
dropdownSeparator: {
height: 1,
backgroundColor: 'cornflowerblue'
},
And this is the hosting component:
render() {
var totalIncome = this.props.balance.totalIncome;
var totalExpanses = this.props.balance.totalExpanses;
return (
<View style={{flex:1, justifyContent: 'space-between'}}>
<Image pointerEvents='none' source={require('../../res/background.png')} style={styles.container} />
<MainScreenHeader onSettingPress={this._onBalanceSettingsPress.bind(this)}/>
<MainBalanceCounter totalCount={totalIncome} currentCount={totalIncome-totalExpanses} />
<View style={{justifyContent: 'center', alignItems: 'center', marginBottom: 150}}>
<AddPaymentButton onPress={this._onAddPaymentPress.bind(this)} />
<PaymentPopup
open={this.state.paymentPopupOpen}
onAddPaymentClicked={this._onPaymentPopupAddClicked.bind(this)} />
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
width: undefined,
height: undefined,
backgroundColor:'transparent',
justifyContent: 'center',
alignItems: 'center',
},
innerContainer: {
justifyContent: 'space-around',
alignItems: 'center',
flex: 1,
backgroundColor: 'transparent'
},
});
I was trying man things to have a view that will catch clicks that happens outside of the popup, but no success.
Any help will be much appreciated,
Thanks,
Giora.
have you tried out react-native-modalbox? I use it in my applications and it works pretty great. If you have touch events behind the modal, it will close. Also, you can define how large you'd like the modal to be. It doesn't have to take up the whole screen.
Otherwise, you were on the right track. You'd need a TouchableWithoutFeedback component that covers the full width and height of the screen. Your popup would be alongside of this component with a higher zIndex. Let me know if you'd like to go this route and I can provide more advice. Cheers!