I’m having trouble with my login view on Android. Whenever I click on an input field, the keyboard show up and push the view up too much. On iOS, it works flawlessly. I tried the KeyboardAvoidView and the react-native-keyboard-aware-scroll-view lib. Nothing works.
I put my KeyboardAvoidView in different places, it didn’t solve my problem. Im running out of options. As far as I know, Android does it automatically, but what can I do when it doesn’t do it right?
Here is my code:
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
TextInput,
TouchableOpacity,
Alert,
Linking,
ImageBackground,
KeyboardAvoidingView,
Platform
} from 'react-native';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { Constants } from 'expo';
import { login } from '../redux/actions';
import Button from '../components/Button';
import CustomCheckBox from '../components/CustomCheckBox';
import ErrorBox from '../components/ErrorBox';
const recuperarSenhaUrl = 'https://baladapp.com.br/recuperar-senha';
const backgroundImage = require('../../assets/images/splash.png')
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
keyboardViewContainer: {
width: '100%',
alignItems: 'center'
},
input: {
width: '80%',
height: 16.7 * 3,
borderRadius: 1.7 * 3,
fontSize: 4.7 * 3,
fontFamily: 'roboto-medium-500',
backgroundColor: '#ffffff',
paddingHorizontal: 6 * 3,
},
esqueceuView: {
width: '80%',
},
esqueceuSenha: {
fontFamily: 'roboto-medium-500',
letterSpacing: 0,
color: '#ffffff',
fontSize: 5 * 3,
marginTop: 8 * 3,
marginBottom: 8 * 3,
},
buttonText: {
fontFamily: 'roboto-medium-500',
color: '#ffffff',
fontSize: 4.7 * 3,
},
button: {
borderRadius: 1.7 * 3,
backgroundColor: '#de0059',
},
continuarConectadoView: {
flexDirection: 'row',
width: '80%'
// justifyContent: 'space-between'
},
continuarConectadoText: {
fontFamily: 'roboto-medium-500',
letterSpacing: 0,
color: '#ffffff',
fontSize: 5 * 3,
marginTop: 2 * 3,
marginBottom: 8 * 3,
marginLeft: 3 * 3
},
versao: {
color: '#ffffff',
fontFamily: 'roboto-regular',
fontSize: 16,
position: 'absolute',
top: '90%'
}
});
class Login extends Component {
constructor(props) {
super(props);
this.fazerLogin = this.fazerLogin.bind(this);
this.switch = this.switch.bind(this);
this.state = {
email: '',
senha: '',
continuarConectado: true
};
}
esqueciMinhaSenha = () => {
// this.props.navigation.navigate('RecuperarSenha', {email: this.state.email})
Linking.openURL(recuperarSenhaUrl)
.catch(err => {
Alert.alert('Ops, um erro ocorreu', err, [{ text: 'OK' }], { cancelable: false });
}
);
};
fazerLogin() {
const { email, senha, continuarConectado } = this.state;
this.props.login(email.trim(), senha.trim(), continuarConectado);
}
switch(value) {
this.setState({continuarConectado: value});
}
render() {
const { erroLogin, logando } = this.props;
return (
<ImageBackground style={styles.container} source={backgroundImage}>
<KeyboardAvoidingView
style={styles.keyboardViewContainer}
behavior={Platform.OS === 'ios' ? 'padding' : null}
>
<Text
style={{
fontFamily: 'roboto-bold',
color: '#ffffff',
fontSize: 48,
marginBottom: 20.7 * 3,
}}
>
Balad<Text style={{ fontFamily: 'roboto-light', color: '#ffffff', fontSize: 48 }}>APP</Text>
</Text>
<TextInput
value={this.state.email}
placeholder="Usuário"
style={[styles.input, { marginBottom: 4 * 3 }]}
placeholderTextColor="#828282"
maxLength={255}
autoCorrect={false}
keyboardType="email-address"
autoCapitalize="none"
returnKeyType="done"
underlineColorAndroid="transparent"
onChangeText={text => this.setState({ email: text })}
/>
<TextInput
value={this.state.senha}
placeholder="Senha"
style={styles.input}
placeholderTextColor="#828282"
maxLength={255}
autoCorrect={false}
autoCapitalize="none"
returnKeyType="done"
secureTextEntry
underlineColorAndroid="transparent"
onChangeText={text => this.setState({ senha: text })}
/>
<View style={styles.esqueceuView}>
<TouchableOpacity onPress={this.esqueciMinhaSenha}>
<Text style={styles.esqueceuSenha}>Esqueceu a senha?</Text>
</TouchableOpacity>
</View>
<CustomCheckBox style={styles.continuarConectadoView} onValueChange={this.switch} value={this.state.continuarConectado}>
<Text style={styles.continuarConectadoText}>Manter conectado</Text>
</CustomCheckBox>
<View style={{ height: 20 * 3, width: '80%' }}>
<Button
title="ACESSAR SISTEMA"
onPress={() => this.fazerLogin()}
titleStyle={styles.buttonText}
buttonStyle={styles.button}
loading={logando}
/>
</View>
</KeyboardAvoidingView>
{erroLogin && (
<View style={{ width: '80%', height: '10%', borderRadius: 1.7 * 3, marginTop: '5%' }}>
<ErrorBox
defaultMessage={
erroLogin.response.status === 401
? 'Email ou senha incorretos'
: 'Ops, houve um erro. Tente novamente'
}
/>
</View>
)}
<Text style={styles.versao}>{Constants.manifest.version}v</Text>
</ImageBackground>
);
}
}
function mapDispatchToProps(dispatch) {
return {
login: (email, senha, continuarConectado) => dispatch(login(email, senha, continuarConectado)),
};
}
function mapStateToProps(state) {
return {
erroLogin: state.config.erroLogin,
logando: state.config.logando,
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Login);
/* eslint-disable */
Login.propTypes = {
erroLogin: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
logando: PropTypes.bool.isRequired,
login: PropTypes.func.isRequired
}
Here what happens (it cuts the title “Baladapp” in half):