react native KeyboardAvoidingView与已打开的键盘不能正常工作

ih99xse1  于 2023-06-24  发布在  React
关注(0)|答案(1)|浏览(119)

在我的应用程序中,有多个显示对话框的情况。当用户应该输入邮件地址并且格式错误时,将在门户内打开react-native-paper对话框。

<Portal>
  <KeyboardAvoidingView behavior={'padding'} style={{flex: 1}}>
     <SafeAreaView style={{flex: 1}}>
        <Dialog>
         [...]

当对话框出现,然后键盘打开,一切都向上移动,它工作正常!当键盘已经打开并出现对话框时,对话框将在键盘后面打开。任何想法如何修复?
我上传了一段视频来展示这种行为:https://streamable.com/zwin42
已经尝试了位置和高度作为行为,但它没有工作以及。

这只发生在iOS上!Android工作正常!

3zwtqj6y

3zwtqj6y1#

这就是我们的工作
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>
   );
}

相关问题