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

React Native中AnimatedTextInput点击后软键盘立即关闭如何解决?

问题根因

你将AnimatedTextInput的创建逻辑放在了TextField组件内部,每次组件的isFocused状态更新触发重渲染时,都会生成一个全新的AnimatedTextInput组件实例,原有输入框会被卸载、新输入框重新挂载,导致原有的输入焦点丢失,软键盘就会自动关闭。

修复方案

第一步:把AnimatedTextInput的创建移到组件外部

全局只需要创建一次动画封装组件,不需要每次组件渲染重复生成:

// 移到组件外部定义
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput)

const TextField = (props) => {
  // 原有组件逻辑,删掉内部的AnimatedTextInput定义
}

第二步:修正onFocus回调的参数传递

你当前的onFocus回调没有传递原生事件参数,有可能拦截了输入框的默认焦点行为,调整为:

<AnimatedTextInput 
  style={[style, styles.input, { paddingTop: paddingTop, paddingBottom: paddingBottom }]} 
  {...restOfProps} 
  onFocus={handleFocus} 
  onBlur={handleBlur} 
  ref={refInput} 
/>

可选兜底方案

如果调整后还有偶现的焦点丢失问题,可以在handleFocus里手动强制输入框保持焦点:

const handleFocus = (input) => {
  console.log('here')
  setIsFocused(true);
  refInput.current?.focus()
}

完整修正后的代码

import React, { useRef } from 'react';
import { Animated, StyleSheet, Text, TextInput, View } from 'react-native';

// 全局定义一次AnimatedTextInput
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput)

const styles = StyleSheet.create({
  input: {
    padding: 24,
    borderColor: 'transparent',
    borderWidth: 1,
    borderRadius: 4,
    fontFamily: 'Avenir-Medium',
    fontSize: 16,
    backgroundColor: '#F8F8F8',
  },
  labelContainer: {
    position: 'absolute',
    left: 16,
    top: 9,
    paddingHorizontal: 8,
  },
  label: {
    color: '#ABB4BD',
    fontFamily: 'Avenir-Heavy',
    fontSize: 12,
  },
})

const TextField = (props) => {
  const { label, style, ...restOfProps } = props;
  const [isFocused, setIsFocused] = React.useState(false);
  const opacity = useRef(new Animated.Value(0)).current;
  const paddingTop = useRef(new Animated.Value(20)).current;
  const paddingBottom = useRef(new Animated.Value(20)).current;

  const refInput = useRef();

  React.useEffect(() => {
    Animated.timing(
      paddingBottom,
      {
        useNativeDriver: false,
        toValue: isFocused ? 10 : 20,
        duration: 200,
      }
    ).start();
    Animated.timing(
      paddingTop,
      {
        useNativeDriver: false,
        toValue: isFocused ? 30 : 20,
        duration: 200,
      }
    ).start();
    Animated.timing(
      opacity,
      {
        useNativeDriver: false,
        toValue: isFocused ? 1 : 0,
        duration: 200,
      }
    ).start();
  }, [isFocused])

  const handleFocus = (input) => {
    console.log('here')
    setIsFocused(true);
    refInput.current?.focus()
  }
  const handleBlur = () => {
    console.log('there')
    setIsFocused(false);
  }

  return (
    <View>
      <AnimatedTextInput style={[style, styles.input, { paddingTop: paddingTop, paddingBottom: paddingBottom }]} {...restOfProps} onFocus={handleFocus} onBlur={handleBlur} ref={refInput} />
      <Animated.View style={[styles.labelContainer, { opacity: opacity}]}>
        <Text style={styles.label}>{label}</Text>
      </Animated.View>
    </View>
  )
};
export default TextField;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 17:24:02