react-native-keyboard-controller icon indicating copy to clipboard operation
react-native-keyboard-controller copied to clipboard

KeyboardAvoadingView padding calculation on keyboard type change is not correct

Open davoam opened this issue 1 year ago • 11 comments

Describe the bug There are two inputs with different keyboard types, and only one is rendered at a time. One input has the default keyboard type, while the other uses 'number-pad'. When we unmount the default text input and show the number input, KeyboardAvoidingView first sets padding as if the default keyboard is displayed, and then adjusts it for the number keyboard.

This transition creates a visible jump that only occurs on Android. In the attached GIF file, you can see that when switching to the numeric keyboard, the footer button is initially rendered higher before moving down.

This issue is easily reproducible with an app created using the latest Expo CLI.

Important: the issue is reproducible with a non-default keyboard. In the example, this keyboard is used. With the default keyboard, everything works as expected.

Code snippet

import { Button , View, TextInput, StatusBar} from 'react-native';
import { useState} from 'react';

import { ThemedText } from '@/components/ThemedText';
import { KeyboardAvoidingView, KeyboardStickyView } from 'react-native-keyboard-controller';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

export default function HomeScreen() {
  const [isNumberFieldDisplayed, setIsNumberFieldDisplayed] = useState(true);
  const insets = useSafeAreaInsets()

  return (
    <View style={{flex: 1}}>
      <KeyboardAvoidingView keyboardVerticalOffset={StatusBar.currentHeight} behavior="padding" style={{flex: 1}}>
        <View style={{flex: 1, paddingTop: insets.top}}>
          <View style={{flex: 1}}>
            <ThemedText type="title">Welcome!</ThemedText>
              <View style={{flex: 1, backgroundColor: 'red'}}>
                <Button title="Change focus" onPress={() => {setIsNumberFieldDisplayed((prevValue) => !prevValue)}} />
                {!isNumberFieldDisplayed && <TextInput autoFocus placeholder="Type something here" placeholderTextColor="black"/>}
                {isNumberFieldDisplayed && <TextInput autoFocus placeholder="Type a number here"placeholderTextColor="black" keyboardType="number-pad"/>}
                <View style={{marginTop: 'auto'}}>
                  <Button title="Footer button" onPress={() => {}} />
                </View>
              </View>  
          </View>
        </View>
      </KeyboardAvoidingView>
    </View>
  );
}

Expected behavior Padding is changed smoothly like it does on iOS.

Screenshots untitled Simulator Screen Recording - iPhone 16 - 2024-11-01 at 12 16 03

Smartphone (please complete the following information):

  • Desktop OS: MacOS 15.0.1
  • Device: Pixel 8 pro (emulator)
  • OS: Android 14
  • RN version: 0.74.5
  • RN architecture: old
  • Library version: 1.14.3

davoam avatar Nov 01 '24 09:11 davoam