首页 > 解决方案 > 如何让键盘在 React native 中正确避免视图

问题描述

问题:

我已经创建了一个与键盘避免视图反应本机的表单,但是当输入字段的所有错误消息都已显示时,视图并没有避免键盘。这是我的代码。

import React, { useEffect } from "react";
import {
  Text,
  View,
  BackHandler,
  KeyboardAvoidingView,
  TouchableOpacity,
  TextInput,
} from "react-native";
import Icon from "react-native-vector-icons/FontAwesome";
import { Formik } from "formik";
import * as Yup from "yup";
import AppText from "_components/appText";
import { strings } from "_translations/i18n";
import styles from "./newpatientstyles";
import SubmitButton from "_components/submitButton";

const NewPatient = () => {
  return (
    <KeyboardAvoidingView style={{ flex: 1 }} enabled>
      <View style={styles.patientView}>
        <View style={styles.patientTitleView}>
          <AppText styles={styles.patientTitle}>
            {strings("new-patient.title")}
          </AppText>
        </View>
        <View style={styles.patient}>
          <View style={styles.patientContainer}>
            <AppText styles={styles.patientFormTitle}>
              {strings("new-patient.form-title")}
            </AppText>
            <View style={styles.formContainer}>
              <Formik
                initialValues={{
                  firstname: "",
                  lastname: "",
                  address: "",
                  age: "",
                  gender: "",
                  mobileNo: "",
                }}
                validationSchema={Yup.object({
                  firstname: Yup.string().required("First Name required"),
                  lastname: Yup.string().required("Last Name required"),
                  address: Yup.string().required("Address required"),
                  age: Yup.string().required("Age required"),
                  gender: Yup.string().required("Gender required"),
                  mobileNo: Yup.string().required("Mobile No required"),
                })}
                onSubmit={(values, formikActions) => {
                  // _onPress(values);
                  setTimeout(() => {
                    formikActions.setSubmitting(false);
                  }, 500);
                }}
              >
                {(formprops) => (
                  <View>
                    <View style={styles.inputView}>
                      <TextInput
                        style={styles.textField}
                        placeholder="Firstname"
                        placeholderTextColor="#bbbbbb"
                        value={formprops.values.firstname}
                        onChangeText={formprops.handleChange("firstname")}
                        onBlur={formprops.handleBlur("firstname")}
                        keyboardType="default"
                      />
                    </View>
                    {formprops.touched.firstname &&
                    formprops.errors.firstname ? (
                      <View style={styles.errorMessage}>
                        <AppText styles={styles.errorMessageText}>
                          {formprops.errors.firstname}
                        </AppText>
                      </View>
                    ) : null}
                    <View style={styles.inputView}>
                      <TextInput
                        style={styles.textField}
                        placeholder="Lastname"
                        placeholderTextColor="#bbbbbb"
                        value={formprops.values.lastname}
                        onChangeText={formprops.handleChange("lastname")}
                        onBlur={formprops.handleBlur("lastname")}
                        keyboardType="default"
                      />
                    </View>
                    {formprops.touched.lastname && formprops.errors.lastname ? (
                      <View style={styles.errorMessage}>
                        <AppText styles={styles.errorMessageText}>
                          {formprops.errors.lastname}
                        </AppText>
                      </View>
                    ) : null}
                    <View style={styles.inputView}>
                      <TextInput
                        style={styles.textField}
                        placeholder="Address"
                        placeholderTextColor="#bbbbbb"
                        value={formprops.values.address}
                        onChangeText={formprops.handleChange("address")}
                        onBlur={formprops.handleBlur("address")}
                        keyboardType="default"
                      />
                    </View>
                    {formprops.touched.address && formprops.errors.address ? (
                      <View style={styles.errorMessage}>
                        <AppText styles={styles.errorMessageText}>
                          {formprops.errors.address}
                        </AppText>
                      </View>
                    ) : null}
                    <View
                      style={
                        (!formprops.touched.age ? styles.inputView : null) ||
                        (formprops.touched.age && formprops.values.age
                          ? styles.validInputView
                          : null) ||
                        (formprops.touched.age && formprops.errors.age
                          ? styles.inputViewError
                          : null)
                      }
                    >
                      <TextInput
                        style={styles.textField}
                        placeholder="Age"
                        placeholderTextColor="#bbbbbb"
                        value={formprops.values.age}
                        onChangeText={formprops.handleChange("age")}
                        onBlur={formprops.handleBlur("age")}
                        keyboardType="default"
                      />
                    </View>
                    {formprops.touched.age && formprops.errors.age ? (
                      <View style={styles.errorMessage}>
                        <AppText styles={styles.errorMessageText}>
                          {formprops.errors.age}
                        </AppText>
                      </View>
                    ) : null}
                    <View
                      style={
                        (!formprops.touched.mobileNo
                          ? styles.inputView
                          : null) ||
                        (formprops.touched.mobileNo && formprops.values.mobileNo
                          ? styles.validInputView
                          : null) ||
                        (formprops.touched.mobileNo && formprops.errors.mobileNo
                          ? styles.inputViewError
                          : null)
                      }
                    >
                      <TextInput
                        style={styles.textField}
                        placeholder="Mobile No"
                        placeholderTextColor="#bbbbbb"
                        value={formprops.values.mobileNo}
                        onChangeText={formprops.handleChange("mobileNo")}
                        onBlur={formprops.handleBlur("mobileNo")}
                        keyboardType="default"
                      />
                      {formprops.touched.mobileNo &&
                      formprops.errors.mobileNo ? (
                        <Icon name="times" size={25} style={styles.errorIcon} />
                      ) : null}
                      {formprops.touched.mobileNo &&
                      formprops.values.mobileNo ? (
                        <Icon name="check" size={25} style={styles.validIcon} />
                      ) : null}
                    </View>
                    {formprops.touched.mobileNo && formprops.errors.mobileNo ? (
                      <View style={styles.errorMessage}>
                        <AppText styles={styles.errorMessageText}>
                          {formprops.errors.mobileNo}
                        </AppText>
                      </View>
                    ) : null}
                    <SubmitButton
                      onpress={formprops.handleSubmit}
                      btext={strings("login.button-text")}
                    />
                  </View>
                )}
              </Formik>
            </View>
          </View>
        </View>
        <View style={styles.hr} />
        <View style={styles.patientBottomContainer}>
          <View style={styles.patientBottomView}>
            <TouchableOpacity>
              <AppText styles={styles.bottomLinkText}>
                {strings("new-patient.bottom-link")}
              </AppText>
            </TouchableOpacity>
          </View>
        </View>
      </View>
    </KeyboardAvoidingView>
  );
};

export default NewPatient;

这就是我组织样式的方式。

import {StyleSheet} from 'react-native';

const styles = StyleSheet.create({
  colempty: {
    height: 150,
  },
  patient: {
    flex: 1,
  },
  patientView: {
    flex: 1,
    backgroundColor: '#eeeeee',
    flexDirection: 'column',
  },
  patientTitleView: {
    alignItems: 'center',
    marginTop: '5%',
  },
  patientTitle: {
    fontSize: 20,
    fontWeight: '300',
    fontStyle: 'normal',
    textAlign: 'center',
    color: '#444444',
  },
  patientFormTitle: {
    fontSize: 25,
    fontWeight: '200',
    fontStyle: 'normal',
    textAlign: 'center',
    color: '#444444',
    alignItems: 'center',
    marginTop: 10,
  },
  hr: {
    marginTop: -30,
    borderBottomColor: '#c3c3c3',
    borderBottomWidth: 2.0,
    marginRight: 30,
    marginLeft: 30,
  },
  patientBottomContainer: {
    height: 50,
  },
  patientBottomView: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
  },
  patientBottomContainerText: {
    fontSize: 13,
    color: '#444444',
    fontWeight: '500',
  },
  formContainer: {
    flex: 1,
    marginRight: 30,
    marginLeft: 30,
  },
  patientBottomLinkView: {
    paddingLeft: 20,
    flex: 1,
    alignItems: 'flex-start',
    justifyContent: 'center',
  },
  patientBottomContainerTextView: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'flex-end',
    paddingLeft: 30,
  },
  bottomLinkText: {
    fontSize: 13,
    color: '#484848',
    borderBottomWidth: 2,
    borderBottomColor: '#c3c3c3',
  },
  errorMessage: {},
  errorMessageText: {
    color: '#ff3d3d',
    fontSize: 18,
    marginTop: 10,
  },
  patientContainer: {
    marginTop: 20,
    backgroundColor: '#f2f2f2',
    height: 600,
    elevation: 10,
    shadowColor: '#000',
    shadowOffset: {width: 0, height: 3},
    shadowOpacity: 0.5,
    shadowRadius: 5,
  },
  submitButtonView: {
    marginTop: 30,
  },
  patienterrorInput: {
    marginTop: 40,
    borderBottomColor: '#ff3d3d',
    fontFamily: 'Montserrat-Medium',
    borderBottomWidth: 2,
    fontSize: 16,
    fontWeight: '500',
  },
  inputView: {
    marginTop: 5,
    flexDirection: 'row',
    borderBottomColor: '#cccccc',
    borderBottomWidth: 2,
  },
  inputViewError: {
    // flex: 1,
    marginTop: 5,
    flexDirection: 'row',
    borderBottomColor: '#ff3d3d',
    borderBottomWidth: 2,
  },
  validInputView: {
    marginTop: 5,
    flexDirection: 'row',
    borderBottomColor: '#007aff',
    borderBottomWidth: 2,
  },
  errorIcon: {
    marginTop: 15,
    color: '#ff3d3d',
  },
  validIcon: {
    marginTop: 15,
    color: '#007aff',
  },
  textField: {
    flex: 1,
    fontFamily: 'Montserrat-Medium',
    fontSize: 16,
    fontWeight: '500',
    paddingLeft: 0,
  },
});

export default styles;

这是加载外观时的视图。 在此处输入图像描述

这是显示所有错误消息时视图的外观。

在此处输入图像描述

有人可以帮我正确使用这个键盘避免视图吗?我尝试了很多让它工作,但我无法这样做。谢谢

标签: react-native

解决方案


对于这些情况,我们可以使用以下方法之一:

1.包装组件<ScrollView></ScrollView>

2.wrapping 组件<KeyboardAvoidingView></KeyboardAvoidingView>如果您已经在使用此方法,请查看https://reactnative.dev/docs/keyboardavoidingview#keyboardverticaloffset

有时我们错误的给定样式也会导致这些情况发生,例如:为我们的样式设置一个固定值,检查您的边距并使用给定的方法之一

我希望它有帮助


推荐阅读