当键盘已经打开并且 render() 更新以显示 KeyboardAvoidingView(以前没有显示)时,它不会避开键盘



所以我有一个餐厅列表,上面和下面都有一个过滤器,当你键入匹配过滤器时,餐厅会更新。当你的过滤器没有返回任何内容时,视图被改变为显示"0";找不到餐馆,请更换过滤器";键入消息。我把它设置为KeyboardAvoidingView,因为我希望它垂直居中,当你打开键盘时,它几乎就在它上面,看起来不太好。然而,当视图处于活动状态时,它会向上推一点,并以可见的内容为中心。

我的问题是,一旦使用了足够多的过滤器来隐藏所有餐厅,KAV就会显示在渲染功能中,但不会识别出键盘是打开的,它需要移动。如果我到了那个阶段,然后关闭/重新打开键盘,它就会工作,但这远非理想。

我已经检查了这个线程,并尝试了在那里找到的解决方案:KeyboardAvoidingView-当键盘被隐藏时重置高度,但不幸的是,这对我来说不起作用。

这个线程似乎和我有同样的问题:用已经打开的键盘反应原生KeyboardAvoidingView无法正常工作,但解决方案是隐藏键盘,这是我不想要的。我希望他们纠正他们的输入,并立即使用已经打开的键盘减少过滤器。

有没有一种方法可以在键盘已经打开后引入KAV,并让它对已经打开的键盘做出反应?

UPDATE:尝试使用此lib:https://github.com/kirillzyusko/react-native-keyboard-controller它解决了我们的很多问题。


这就是我们的工作原理

  1. 我们需要创建一个钩子,告诉我们键盘将隐藏(我们稍后需要它(:
import { useEffect, useState } from 'react';
import { Keyboard } from 'react-native';
export const useKeyboardVisible = () => {
const [isKeyboardWillHide, setKeyboardWillHide] = useState(false);
useEffect(() => {
const keyboardWillHideListener = Keyboard.addListener('keyboardWillHide', () => {
setKeyboardWillHide(true);
});
return () => {
keyboardWillHideListener.remove();
};
}, []);
return { isKeyboardWillHide };
};
  1. 接下来,我们需要创建一个钩子,该钩子将返回动画marginBottom样式(用于平滑布局更改(:
  • 使用Keyboard.isVisible();确定键盘已经可见
  • 使用Keyboard.metrics()获取键盘高度
  • 如果键盘可见->设置marginBottom=keyboard height
import { Keyboard } from 'react-native';
import { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
const useKeyboardAlreadyVisibleMarginFix = () => {
const { isKeyboardWillHide } = useKeyboardVisible();
const marginBottom = useSharedValue(0);
const animatedStyle = useAnimatedStyle(() => {
return {
marginBottom: marginBottom.value
? marginBottom.value
: withTiming(0, {
duration: 300,
}),
};
}, []);
useEffect(() => {
const isVisible = Keyboard.isVisible();
const metrics = Keyboard.metrics();
if (isVisible) {
marginBottom.value = metrics?.height ?? 0;
}
if (isKeyboardWillHide) {
marginBottom.value = 0;
}
return () => {
marginBottom.value = 0;
};
}, [isKeyboardWillHide, marginBottom]);
return { animatedStyle };
};
  1. 使用`Animated.View使布局动画更加用户友好:
import { Keyboard, KeyboardAvoidingView, Platform } from 'react-native';
import { useHeaderHeight } from '@react-navigation/elements';
import Animated from 'react-native-reanimated';
// ...
const height = useHeaderHeight();
const { animatedStyle } = useKeyboardAlreadyVisibleMarginFix();
if (Platform.OS === 'ios') {
return (
<KeyboardAvoidingView behavior="padding" style={{flex: 1}} keyboardVerticalOffset={height}>
<Animated.View style={[{ flex: 1 }, animatedStyle]}>{children}</Animated.View>
</KeyboardAvoidingView>
);
}

最新更新