Ana Laura T.
Ana Laura T.

Reputation: 670

Overlap using KeyboardAvoidingView in a React Native project tested in Android

I'm creating a login, and to solve the problem with the virtual keyboard covering my text inputs I'm using KeyboardAvoidingView. I thought that the logo would animate nicely since I define both the form and the logo as flex: 1 (shrink/grow as much as possible in the available space) Since opening a keyboard diminishes the available space on the screen, the logo does change, but shrinks too much and then an overlap occurs. What I am missing?

This is my LoginScreen:

import React, { Component } from 'react'
import { Image, StyleSheet, View, KeyboardAvoidingView, Button } from 'react-native'
import FormTextInput from '../components/FormTextInput'

class LoginScreen extends Component {
  state = { email: '', password: '' }

  handleEmailUpdate = email => {
    this.setState({ email })
  }

  handlePasswordUpdate = password => {
    this.setState({ password })
  }

  handleLoginPress = () => {
    console.log('Login button pressed')
  }

  render() {
    return (
      <KeyboardAvoidingView style={styles.container} behavior="padding">
        <Image style={styles.logo} source={require('../assets/images/test.png')} />

        <View style={styles.form}>
          <FormTextInput
            value={this.state.email}
            onChangeText={this.handleEmailChange}
            placeholder="Email"
            autoCorrect={false}
            keyboardType="email-address"
            returnKeyType="next"
          />
          <FormTextInput
            placeholder="Password"
            value={this.state.password}
            onChangeText={this.handlePasswordChange}
            secureTextEntry
            returnKeyType="done"
          />
          <Button title="LOGIN" onPress={this.handleLoginPress} />
        </View>
      </KeyboardAvoidingView>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  logo: {
    flex: 1,
    width: '80%',
    resizeMode: 'contain',
    alignSelf: 'center',
  },
  form: {
    flex: 1,
    justifyContent: 'center',
    width: '80%',
  },
})

export default LoginScreen

problem

*EDIT: after adding the line android:windowSoftInputMode="adjustPan", the keyboard overlaps the login button:

new problem

Upvotes: 0

Views: 6773

Answers (2)

Anurag Shrivastava
Anurag Shrivastava

Reputation: 692

try this.

    {Platform.OS === 'ios' ?
                <KeyboardAvoidingView style={styles.container} behavior="padding">
                    <ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={{paddingVertical: 10}}
                                keyboardShouldPersistTaps='handled'>

                        <Image style={styles.logo} source={require('../assets/images/test.png')} />
                        <View style={styles.form}>
                         <FormTextInput
                           value={this.state.email}
                           onChangeText={this.handleEmailChange}
                           placeholder="Email"
                           autoCorrect={false}
                           keyboardType="email-address"
                           returnKeyType="next"
                         />
                         <FormTextInput
                           placeholder="Password"
                           value={this.state.password}
                           onChangeText={this.handlePasswordChange}
                           secureTextEntry
                           returnKeyType="done"
                         />
                         <Button title="LOGIN" onPress={this.handleLoginPress} />
                      </View>
                    </ScrollView>
                </KeyboardAvoidingView>
                : <ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={{paddingVertical: 10}}
                              keyboardShouldPersistTaps='handled'>


                    <Image style={styles.logo} source={require('../assets/images/test.png')} />
                        <View style={styles.form}>
                         <FormTextInput
                           value={this.state.email}
                           onChangeText={this.handleEmailChange}
                           placeholder="Email"
                           autoCorrect={false}
                           keyboardType="email-address"
                           returnKeyType="next"
                         />
                         <FormTextInput
                           placeholder="Password"
                           value={this.state.password}
                           onChangeText={this.handlePasswordChange}
                           secureTextEntry
                           returnKeyType="done"
                         />
                         <Button title="LOGIN" onPress={this.handleLoginPress} />
                      </View>
                </ScrollView>
    }

and style is

const styles = StyleSheet.create({
container: {
    flex: 1, paddingVertical: 30,
    alignItems: 'center', justifyContent: 'center',
    backgroundColor: '#FFFFFF',
},
logo: {
    flexGrow: 1,
    width: '80%',
    resizeMode: 'contain',
    alignSelf: 'center',
},
form: {
    flexGrow: 1,
    justifyContent: 'center',
    width: '80%',
},

});

Upvotes: 0

Ashutosh Patel
Ashutosh Patel

Reputation: 111

Use this is your android manifest

<activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
            android:screenOrientation="portrait"
            android:launchMode="singleTop"
            android:windowSoftInputMode="adjustPan" //add this line
            android:exported="true">

try this it will solve this problem

Upvotes: 3

Related Questions