React Native <TextInput> Android端onBlur更新样式致文本消失问题求助
解决React Native Android端TextInput onBlur时文本消失的问题
我之前也碰到过Android端TextInput这种诡异的样式更新bug,iOS端正常但Android改textAlign就丢文本,本质是Android原生EditText在动态调整对齐方式时,重绘逻辑出现了小问题,没正确渲染文本内容。下面给你两个靠谱的解决办法:
方案一:手动触发组件刷新(简单直接)
我们可以在onBlur回调里,通过设置文本选区的方式强制Android端重新渲染文本,绕开原生的渲染bug:
import React, { useState, useRef } from 'react'; import { TextInput, View } from 'react-native'; export default function App() { const [isFocused, setIsFocused] = useState(false); const inputRef = useRef(null); const handleBlur = () => { setIsFocused(false); // 强制Android端刷新文本显示 if (inputRef.current) { const { selection } = inputRef.current; inputRef.current.setNativeProps({ selection: { start: selection.start, end: selection.end, }, }); } }; const handleFocus = () => { setIsFocused(true); }; return ( <View style={{ padding: 20, marginTop: 50 }}> <TextInput ref={inputRef} style={{ borderWidth: 1, padding: 10, textAlign: isFocused ? 'left' : 'center', }} onFocus={handleFocus} onBlur={handleBlur} placeholder="测试输入内容" /> </View> ); }
方案二:用Animated实现平滑过渡(体验更好)
如果想要样式切换更丝滑,也可以用Animated组件来驱动textAlign的变化,这种方式能避免直接修改style触发的原生渲染异常:
import React, { useRef } from 'react'; import { TextInput, View, Animated } from 'react-native'; export default function App() { const focusAnim = useRef(new Animated.Value(0)).current; const handleFocus = () => { Animated.timing(focusAnim, { toValue: 1, duration: 100, useNativeDriver: false, // textAlign不支持原生驱动 }).start(); }; const handleBlur = () => { Animated.timing(focusAnim, { toValue: 0, duration: 100, useNativeDriver: false, }).start(); }; const textAlign = focusAnim.interpolate({ inputRange: [0, 1], outputRange: ['center', 'left'], }); return ( <View style={{ padding: 20, marginTop: 50 }}> <Animated.TextInput style={{ borderWidth: 1, padding: 10, textAlign, }} onFocus={handleFocus} onBlur={handleBlur} placeholder="测试输入内容" /> </View> ); }
问题根源说明
Android的TextInput底层是基于原生EditText实现的,当动态修改textAlign(对应原生的gravity属性)时,原生组件重绘时偶尔会丢失文本的绘制状态;而iOS的UITextField对这种样式变更的处理逻辑更稳定,所以不会出现这个问题。上面两种方案都是通过不同方式绕过了原生的这个小bug。
内容的提问来源于stack exchange,提问作者Tim Mathis
相关产品推荐
相关产品推荐

