You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo 54 Android端KeyboardAvoidingView收起键盘后无法归位

Android端KeyboardAvoidingView收起键盘后布局偏移问题

问题描述

在基于Expo SDK 54的React Native页面中使用KeyboardAvoidingView实现输入框随键盘上移,键盘弹出时布局符合预期,但收起键盘后视图无法回到初始位置,始终保持轻微上移状态。该问题仅在Android端使用behavior={Platform.OS === 'ios' ? 'padding' : 'height'}时出现。

复现步骤

  • 渲染包含底部对齐(justifyContent: 'flex-end')TextInput的KeyboardAvoidingView
  • 点击输入框唤起键盘
  • 点击外部区域收起键盘
  • 观察到布局未完全恢复至初始状态

预期行为

键盘收起后,视图应完全恢复到初始布局位置。

实际行为

键盘关闭后,视图仍保持轻微向上偏移的状态。

代码示例

import React from 'react';
import {
  View,
  KeyboardAvoidingView,
  TextInput,
  StyleSheet,
  Platform,
  TouchableWithoutFeedback,
  Button,
  Keyboard,
} from 'react-native';

const KeyboardAvoidingComponent = () => {
  return (
    <KeyboardAvoidingView
      behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
      style={styles.container}>
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <View style={styles.inner}>
          <TextInput placeholder="Username" style={styles.textInput} />
          <Button title="Submit" onPress={() => null} />
        </View>
      </TouchableWithoutFeedback>
    </KeyboardAvoidingView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  inner: {
    flex: 1,
    justifyContent: 'flex-end',
  },
  textInput: {
    height: 40,
    borderBottomWidth: 1,
    marginBottom: 36,
  },
});

export default KeyboardAvoidingComponent;

环境信息

  • Expo SDK: 54
  • 平台: Android
  • React Native: 0.81.5

示意图

  • 初始布局:初始布局
  • 键盘弹出时布局:键盘弹出时布局
  • 键盘收起后偏移布局:键盘收起后偏移布局

解决方案

方案1:统一Android端的behavior为padding

将Android端的behavior配置从height改为padding,与iOS端保持一致:

behavior="padding"
// 或者保留平台判断写法:behavior={Platform.OS === 'ios' ? 'padding' : 'padding'}

height模式在Android端容易出现键盘收起后的布局计算偏差,padding模式的适配逻辑更稳定,能确保布局正确恢复到初始状态。

方案2:手动监听键盘收起事件触发重绘

通过监听keyboardDidHide事件,使用LayoutAnimation强制触发组件重绘,修正布局偏移:

import React, { useEffect } from 'react';
import {
  View,
  KeyboardAvoidingView,
  TextInput,
  StyleSheet,
  Platform,
  TouchableWithoutFeedback,
  Button,
  Keyboard,
  LayoutAnimation,
} from 'react-native';

const KeyboardAvoidingComponent = () => {
  useEffect(() => {
    const keyboardHideListener = Keyboard.addListener(
      'keyboardDidHide',
      () => {
        LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
      }
    );

    return () => keyboardHideListener.remove();
  }, []);

  return (
    <KeyboardAvoidingView
      behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
      style={styles.container}>
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <View style={styles.inner}>
          <TextInput placeholder="Username" style={styles.textInput} />
          <Button title="Submit" onPress={() => null} />
        </View>
      </TouchableWithoutFeedback>
    </KeyboardAvoidingView>
  );
};

// 样式部分不变
const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  inner: {
    flex: 1,
    justifyContent: 'flex-end',
  },
  textInput: {
    height: 40,
    borderBottomWidth: 1,
    marginBottom: 36,
  },
});

export default KeyboardAvoidingComponent;

方案3:使用第三方库替代KeyboardAvoidingView

如果原生组件的问题无法解决,可以尝试使用react-native-keyboard-aware-scroll-view,它对键盘适配的处理更完善:

  1. 安装依赖:
npx expo install react-native-keyboard-aware-scroll-view
  1. 修改组件代码:
import React from 'react';
import {
  View,
  TextInput,
  StyleSheet,
  TouchableWithoutFeedback,
  Button,
  Keyboard,
} from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';

const KeyboardAvoidingComponent = () => {
  return (
    <KeyboardAwareScrollView
      style={styles.container}
      enableOnAndroid={true}
      keyboardShouldPersistTaps="handled"
    >
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <View style={styles.inner}>
          <TextInput placeholder="Username" style={styles.textInput} />
          <Button title="Submit" onPress={() => null} />
        </View>
      </TouchableWithoutFeedback>
    </KeyboardAwareScrollView>
  );
};

// 样式部分不变
const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  inner: {
    flex: 1,
    justifyContent: 'flex-end',
  },
  textInput: {
    height: 40,
    borderBottomWidth: 1,
    marginBottom: 36,
  },
});

export default KeyboardAvoidingComponent;

内容的提问来源于stack exchange,提问作者di0n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 14:19:53