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

React Native Android:如何让键盘弹出时UI元素保持原位?

React Native Android 禁用键盘弹出时UI上移的解决方案

在React Native Android项目中,当输入文本、键盘弹出时,UI元素会被向上移动。希望取消该功能,让所有UI元素保持原有位置(即使被键盘覆盖也无影响),添加KeyboardAvoidingView并未解决此问题,请问该如何实现?

核心原因

Android系统默认采用adjustResize模式,键盘弹出时会自动调整布局高度,加上你的Modal内使用了大量top/bottom绝对定位属性,进一步加剧了UI位移问题。

解决方案

方法一:全局禁用键盘布局调整(推荐)

修改Android项目的android/app/src/main/AndroidManifest.xml文件,找到主Activity(通常为MainActivity),将android:windowSoftInputMode设置为adjustNothing,让系统完全不调整布局:

<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
    android:launchMode="singleTask"
    android:windowSoftInputMode="adjustNothing"
    android:exported="true">

方法二:针对单个Modal禁用调整

如果不想全局修改布局规则,可以在Modal内部的最外层包裹KeyboardAvoidingView,并禁用其自动调整行为:

<KeyboardAvoidingView
    style={{ flex: 1 }}
    behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
    enabled={false} // 关闭自动调整逻辑
>
    {/* Modal内部的ImageBackground及其他UI元素 */}
</KeyboardAvoidingView>

修改后的完整代码

import React from 'react';
import { View, TextInput, Modal, ImageBackground, KeyboardAvoidingView, TouchableOpacity, Image, Platform, StyleSheet, Text } from 'react-native';

const App = () => {
    return (
        <View>
            <Modal
                animationType="slide"
                transparent={true}
                visible={true}
            >
                <KeyboardAvoidingView
                    style={{ flex: 1 }}
                    behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
                    enabled={false}
                >
                    <ImageBackground
                        source={require('./assets/images/Red.png')}
                        style={styles.imageBackground}
                    >
                        <View
                            style={[
                                styles.roundedRectangleInIncomeView,
                                {
                                    height: 400,
                                    display: 'flex',
                                },
                            ]}
                        />
                        <View style={styles.addingIncomeModalContainer}>
                            <View style={styles.addingIncomeModalContent}>
                                <TouchableOpacity
                                    style={styles.backButtonOnIncomeScreen}
                                    onPress={() => {}}
                                >
                                    <Image source={require('./assets/images/BackArrowWhite.png')} />
                                </TouchableOpacity>
                                <Text style={styles.headerForNewIncomeWindow}>
                                    '123'
                                </Text>
                                <Text style={styles.headerForTextWithNumberOnIncomeScreen}>
                                    '123'
                                </Text>
                                <Text style={styles.textWithNumberOnIncomeScreen}>
                                    '8'
                                </Text>
                                <TextInput
                                    style={styles.inputIncomeDescription}
                                    placeholder={'567'}
                                    value={'789'}
                                />
                                <TextInput
                                    style={styles.inputIncomeAmount}
                                    placeholder={'876'}
                                    keyboardType="numeric"
                                    value={'123'}
                                />
                                <TouchableOpacity
                                    style={styles.addDateButtonOnIncomeScreen}
                                    onPress={() => {}}
                                >
                                    <Text style={styles.addDateButtonOnIncomeScreenText}>{768}</Text>
                                </TouchableOpacity>
                                <TouchableOpacity onPress={() => {}} style={styles.saveButtonOnIncomeScreen}>
                                    <Text style={styles.buttonText}>{'456'}</Text>
                                </TouchableOpacity>
                            </View>
                        </View>
                    </ImageBackground>
                </KeyboardAvoidingView>
            </Modal>
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'flex-end',
        alignItems: 'center',
        bottom: -520,
    },
    text: {
        fontSize: 20,
        marginBottom: 10,
    },
    input: {
        height: 50,
        width: '80%',
        borderColor: 'gray',
        borderWidth: 1,
        paddingLeft: 10,
        borderRadius: 5,
    },
    imageBackground: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        width: '100%',
        resizeMode: 'cover',
    },
    addDateButtonOnIncomeScreen: {
        width: 300,
        height: 40,
        backgroundColor: '#fff',
        borderRadius: 15,
        justifyContent: 'center',
        alignItems: 'center',
        marginBottom: 20,
        top: 110,
    },
    saveButtonOnIncomeScreen: {
        width: 300,
        height: 40,
        backgroundColor: '#ff0030',
        borderRadius: 15,
        justifyContent: 'center',
        alignItems: 'center',
        marginBottom: 20,
        top: 100,
    },
    inputIncomeDescription: {
        backgroundColor: 'white',
        padding: 5,
        marginTop: 10,
        top: 100,
        borderRadius: 15,
        width: 300,
        height: 40,
        textAlign: 'center',
    },
    inputIncomeAmount: {
        backgroundColor: 'white',
        padding: 5,
        marginTop: 10,
        top: 100,
        borderRadius: 15,
        width: 300,
        height: 40,
        textAlign: 'center',
    },
    backButtonOnIncomeScreen: {
        right: 150,
        bottom: 117,
    },
    addingIncomeModalContainer: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
    addingIncomeModalContent: {
        padding: 20,
        borderRadius: 10,
        alignItems: 'center',
    },
    textWithNumberOnIncomeScreen: {
        color: 'white',
        fontWeight: 'bold',
        fontSize: 60,
        top: -5,
    },
    headerForNewIncomeWindow: {
        color: 'white',
        fontWeight: 'bold',
        fontSize: 20,
        top: -140,
    },
    headerForTextWithNumberOnIncomeScreen: {
        color: 'white',
        fontWeight: 'bold',
        fontSize: 20,
        top: -10,
    },
    roundedRectangleInIncomeView: {
        backgroundColor: '#ebf1f4',
        width: '100%',
        borderTopLeftRadius: 40,
        borderTopRightRadius: 40,
        borderBottomLeftRadius: 0,
        borderBottomRightRadius: 0,
        position: 'absolute',
        bottom: 0,
        transform: [{ scale: 1 }]
    },
});

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 10:10:07