React Native Keyboard避免视图覆盖最后的文本输入

问题描述 投票:0回答:7

我正在使用 React Native 的 KeyboardvoidingView,并将行为设置为填充(在 Android 上测试)。

我的屏幕上有多个文本输入。当我单击最后一个 TextInput 时,键盘会覆盖它。由于从 KeyboardAvoidingView 添加了填充,我现在可以向下滚动,但最好让它在焦点上自动滚动。

<Content>
  <KeyboardAvoidingView behavior='padding'>
    <TextInput placeholder='Example 1' />
    <TextInput placeholder='Example 2' />
    <TextInput placeholder='Example 3' />
    <TextInput placeholder='Example 4' />
    <TextInput placeholder='Example 5' />
    <TextInput placeholder='Example 6' />
    <TextInput placeholder='Example 7' />
  </KeyboardAvoidingView>
</Content>
javascript react-native
7个回答
91
投票

有一个名为keyboardVerticalOffset的属性,您可以将其传递给KeyboardAvoidingView,它将改变键盘移过textInput的距离。 我的代码示例:

const keyboardVerticalOffset = Platform.OS === 'ios' ? 40 : 0

    return (
      <KeyboardAvoidingView behavior='position' keyboardVerticalOffset={keyboardVerticalOffset}>
        <ListView .../>
      <KeyboardAvoidingView/>
    )

41
投票

根据 Android 或 IOS 平台的不同,实现可能会略有不同。我就是这样做的。

在 AndroidManifest.xml 中添加 android:windowSoftInputMode="adjustResize"

 <activity
    android:name=".MainActivity"
    android:launchMode="singleTask"
    android:label="@string/app_name"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
    android:windowSoftInputMode="adjustResize">

 </activity>

在你的容器中

    <KeyboardAvoidingView
      behavior={Platform.OS === "ios" ? "padding" : null}
      keyboardVerticalOffset={Platform.OS === "ios" ? 64 : 0}>
      <ScrollView>
        {...}
      </ScrollView>
    </KeyboardAvoidingView>

keyboardVerticalOffset 告诉键盘移动超过textInput 的距离。


16
投票

反应本机键盘感知滚动视图

使用起来超级简单,并且在 Android 和 iOS 上都运行良好。

它也支持旧版本的 RN。

最初我尝试了

KeyboardAvoidingView
但在IOS上甚至没有

behavior='position'
keyboardVerticalOffset
工作正常。

过去常常以一种奇怪的方式重叠某些内容。

我有:

RN 0.53.3
react-native-keyboard-aware-scroll-view 0.6.0

我在此处添加了有关我的用例的更多详细信息:

https://stackoverflow.com/a/51151496/1979861


7
投票

要添加@Maxwell的答案,有时您可能需要滚动到比滚动视图末尾更远的位置才能将组件放入视图中,因为添加的填充不是键盘的完整高度。下面的完整示例使用scrollTo(),其中 y 偏移量作为文本输入的高度。

import React, { Component } from 'react'
import {
    KeyboardAvoidingView,
    ScrollView,
    View,
    TextInput
} from 'react-native'


export default class Test extends Component {
    render() {
        return (
            <ScrollView style = {{flex:1, backgroundColor: 'white'}} ref = 'scroll'>
              <KeyboardAvoidingView behavior='position' style = {{backgroundColor: 'white', flex: 1}}>
                    <View style = {{height: 400}}/>
                    <TextInput style = {{height: 60}} placeholder='Example 1' />
                    <TextInput style = {{height: 60}} placeholder='Example 2' />
                    <TextInput style = {{height: 60}} placeholder='Example 3' />
                    <TextInput style = {{height: 60}} placeholder='Example 4' onFocus = {() => this.refs['scroll'].scrollTo({y: 60})}/>
              </KeyboardAvoidingView>
            </ScrollView>
        )
    } 
}

4
投票

如果您正在使用react-navigation v6您可能需要

import { useHeaderHeight } from "@react-navigation/elements";

 const headerHeight = useHeaderHeight();

   <KeyboardAvoidingView
        behavior={Platform.OS === "ios" ? "padding" : undefined}
        style={flexGrow}
        keyboardVerticalOffset={Platform.OS === "ios" ? headerHeight + Constants.statusBarHeight : 0}
      >
   </KeyboardAvoidingView>

1
投票

基于@Richard Millen,这种风格发生了一些变化

<ScrollView
  contentContainerStyle={{
    flexGrow: 1,
    padding: 20
  }}
>
  <TextInput
    style = {{ minHeight: 100 }}
  />
  <TextInput
    style = {{ minHeight: 100 }}
  />
  ...
</ScrollView>

0
投票

我遇到的问题是由于react-native-safe-area-context,而不是React Navigation header的高度。我通过使用 useSafeAreaInsets 获取插图来修复它,它提供了一个对象,例如 {"bottom": 34, "left": 0, "right": 0, "top": 59}。然后,我使用该对象的顶部值作为 KeyboardVerticalOffset 属性,如下所示:

import {useSafeAreaInsets} from 'react-native-safe-area-context';
...
    const insets = useSafeAreaInsets();
    ...
      <KeyboardAvoidingView
        behavior="padding"
        keyboardVerticalOffset={insets.top}
        style={styles.container}>
      ...
      </KeyboardAvoidingView>
© www.soinside.com 2019 - 2024. All rights reserved.