-
-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
KeyboardAvoadingView padding calculation on keyboard type change is not correct #672
Comments
Thanks @davoam for raising the issue It's very interesting, that the issue happens only with custom keyboards (i. e. not a stock one). I will have a look on this problem 👀 |
@davoam I think the issue is reproducible with default keyboard as well? See the video below: Screen.Recording.2024-11-03.at.13.12.51.movI think this problem is located in native code. Because let's say if QWERTY keyboard height is For me it looks like it's Android OS bug, but I will see if such problem can be reproduced in native code or can be fixed within this library 👀 |
One potentail solution I'm thinking of is to store a map of key value where key is type of Is it possible to wait for keyboard hide and then trigger input unmount? Or maybe wait for a keyboard to disappear and only when it's hidden request a focus to a new input? Or you can mount a new input, switch focus, and only when focus gets switched then you will remove previous field? What do you think about these approaches? |
Thanks for the quick response, @kirillzyusko ! I tried closing the keyboard, waiting for Mounting new input is also not a good solution since these two inputs may be on different screens. It makes things complex. So, as a temporary hack we used this 1-second delay. We close the keyboard, wait for Here is the code when which works correctly, but if you change import { Button , View, TextInput, StatusBar, Keyboard} from 'react-native';
import { useState, useRef} 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()
const textInputRef = useRef<TextInput | null>(null);
const numberInputRef = useRef<TextInput | null>(null);
const onChangeFocus = () => {
function toggleIsNumberFieldDisplayed() {
setIsNumberFieldDisplayed((prevValue) => {
const nextIsNumberFieldDisplayed = !prevValue
setTimeout(() => {
nextIsNumberFieldDisplayed ? numberInputRef.current?.focus() : textInputRef.current?.focus();
}, 1000);
return nextIsNumberFieldDisplayed;
});
}
if (Keyboard.isVisible()) {
const listener = Keyboard.addListener('keyboardDidHide', () => {
toggleIsNumberFieldDisplayed();
listener.remove();
});
Keyboard.dismiss();
} else {
toggleIsNumberFieldDisplayed();
}
}
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={onChangeFocus} />
{!isNumberFieldDisplayed && <TextInput key="textInput" ref={textInputRef} placeholder="Type something here" placeholderTextColor="black"/>}
{isNumberFieldDisplayed && <TextInput key="numberInput" ref={numberInputRef} 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>
);
} |
@davoam okay interesting - 300ms is a pretty big time interval, so it should work 🤯 I'll have a look again on this problem! It's weird, that you have to wait 1s! |
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
Expected behavior
Padding is changed like smoothly like it does on iOS.
Screenshots
Smartphone (please complete the following information):
The text was updated successfully, but these errors were encountered: