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

Android端Native Base Input嵌套KeyboardAvoidingView无法选中文本问题

问题

在React Native Expo应用中,将Native Base的Input组件嵌套在KeyboardAvoidingView内时,出现以下异常:

  • Android端:可正常输入文本,但无法拖拽或选中文本内容,修改错误只能逐删到对应位置重新输入
  • iOS端:无此问题

移除KeyboardAvoidingView后文本选择功能恢复正常;将KeyboardAvoidingView移至父组件虽能正常选中文本,但会触发页面整体滚动,不符合需求。

目标:保留TitleInput组件内的KeyboardAvoidingView,同时让用户可正常操控输入文本。

解决方案

问题根源是Android端KeyboardAvoidingView的position行为会干扰内部Input组件的触摸事件传递,导致文本选择的交互失效。通过两处调整解决:

  1. 针对Android端,将KeyboardAvoidingView的pointerEvents设置为"box-none",允许触摸事件穿透到内部组件
  2. 调整Android端KeyboardAvoidingView的behavior,避免position带来的层级冲突

修改后的完整代码:

import { Platform, View } from 'react-native';
import UserContext from '@/src/context/UserContext';
import { COLORS, SIZES, rgbaColor } from '@/src/constants/theme';
import { moderateScale } from 'react-native-size-matters';
import React, { useState, useCallback, useContext } from 'react';
import { FormControl, Input, KeyboardAvoidingView, Text } from 'native-base';

const TitleInput = () => {
  const isOldDevice = Platform.constants['Release'] < 12;
  // 针对Android调整behavior,避免position导致的触摸事件问题
  const keyboardBehavior = Platform.select({
    android: !isOldDevice ? 'height' : null,
    ios: !isOldDevice ? 'position' : null,
  });
  const [valueText, setValueText] = useState('');
  const [isFocused, setIsFocused] = useState(false);
  const { setTitle } = useContext(UserContext);

  const handleBlur = useCallback(() => setIsFocused(false), []);
  const handleFocus = useCallback(() => setIsFocused(true), []);

  const handleChange = useCallback(
    value => {
      if (value.length <= 100) setValueText(value);
    },
    []
  );

  const handleEndEditing = useCallback(
    e => {
      const text = e?.nativeEvent?.text;
      if (text && text.length <= 100) setTitle(text);
    },
    [setTitle]
  );

  return (
    <KeyboardAvoidingView
      keyboardVerticalOffset={Platform.OS === 'android' ? 75 : 55}
      behavior={keyboardBehavior}
      // Android端设置pointerEvents,允许触摸事件穿透到内部Input
      pointerEvents={Platform.OS === 'android' ? 'box-none' : 'auto'}
    >
      <View style={{ backgroundColor: COLORS.pureWhite }}>
        <FormControl>
          <Input
            marginX={4}
            maxLength={100}
            textAlign="left"
            borderRadius="full"
            onBlur={handleBlur}
            onFocus={handleFocus}
            onChangeText={handleChange}
            onEndEditing={handleEndEditing}
            placeholder="Stream Title"
            color={COLORS.darkestGray}
            backgroundColor={COLORS.pureWhite}
            padding={Platform.OS === 'ios' ? 4 : 3}
            fontSize={moderateScale(SIZES.extend.regular, 0.1)}
            marginBottom={Platform.select({
              android: isFocused ? 4 : 2,
              ios: isFocused ? SIZES.small : 4,
            })}
            InputRightElement={
              <Text
                paddingTop={5}
                paddingRight={3}
                color={rgbaColor(COLORS.darkestGray, 0.5)}
                fontSize={moderateScale(SIZES.small, 0.1)}
              >
                {valueText.length}/100
              </Text>
            }
          />
        </FormControl>
      </View>
    </KeyboardAvoidingView>
  );
};

export default TitleInput;

关键修改点说明:

  • pointerEvents="box-none":仅对Android生效,让KeyboardAvoidingView不拦截内部组件的触摸事件,确保文本选择、拖拽等交互能正常触发
  • 调整Android端的keyboardBehavior为height:position行为在Android上会改变视图的位置属性,容易引发触摸区域偏移,height通过调整容器高度来规避键盘,更稳定

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:52:47