You need to enable JavaScript to run this app. 如何在React Native中实现带动画效果的自定义浮动标签TextInput
优惠活动
大模型
产品
解决方案
定价
更多

如何在React Native中实现带动画效果的自定义浮动标签TextInput

你需要借助React Native自带的Animated动画API,结合聚焦状态、输入值状态控制标签的位移动画,具体修改如下:

第一步:导入依赖

先在文件顶部引入需要的核心API:

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

第二步:修改组件逻辑

完整的组件代码调整如下:

export default function InputBox(props) {
  const [isFocused, setIsFocused] = useState(false);
  const [inputValue, setInputValue] = useState(props.defaultValue || '');
  // 动画值:0代表标签在输入框内,1代表标签上浮到外部
  const labelAnimation = useRef(new Animated.Value(inputValue ? 1 : 0)).current;

  // 监听状态变化触发动画
  useEffect(() => {
    Animated.timing(labelAnimation, {
      toValue: isFocused || inputValue.trim() !== '' ? 1 : 0,
      duration: 200, // 动画时长可自定义
      easing: Easing.inOut(Easing.ease),
      useNativeDriver: false,
    }).start();
  }, [isFocused, inputValue, labelAnimation]);

  const handleFocus = () => setIsFocused(true);
  const handleBlur = () => setIsFocused(false);
  const handleChangeText = (text) => {
    setInputValue(text);
    props.onChangeText?.(text);
  };

  // 标签动态样式插值
  const labelAnimatedStyle = {
    transform: [
      {
        translateY: labelAnimation.interpolate({
          inputRange: [0, 1],
          outputRange: [18, 0], // 可根据设计稿调整位移数值
        }),
      },
    ],
    fontSize: labelAnimation.interpolate({
      inputRange: [0, 1],
      outputRange: [13, 10],
    }),
    // 不需要聚焦变色可删掉color配置
    color: labelAnimation.interpolate({
      inputRange: [0, 1],
      outputRange: [COLORS.GREY, isFocused ? COLORS.PRIMARY : COLORS.GREY],
    }),
  };

  return (
    <View style={[styles.container, {
      // 可选:聚焦时高亮边框
      borderColor: isFocused ? COLORS.PRIMARY : COLORS.GREY_BORDER
    }]}>
      <Animated.Text style={[styles.label, labelAnimatedStyle]}>
        {props.label}
      </Animated.Text>
      <TextInput
        style={styles.input}
        autoCapitalize="none"
        defaultValue={props.defaultValue}
        onChangeText={handleChangeText}
        keyboardType={props.keyboardType}
        editable={props.editable}
        onFocus={handleFocus}
        onBlur={handleBlur}
        value={inputValue}
      />
    </View>
  );
}

第三步:调整样式

重点修改容器和标签的定位规则,预留标签上浮的空间:

const styles = StyleSheet.create({
  container: {
    marginBottom: 20,
    backgroundColor: COLORS.WHITE,
    paddingTop: 15, // 增加顶部内边距放浮动标签
    paddingHorizontal: 10,
    borderWidth: 1,
    borderColor: COLORS.GREY_BORDER,
    borderRadius: 2,
    position: 'relative',
  },
  icon: {
    width: 40,
    justifyContent: 'center',
    alignItems: 'center',
  },
  input: {
    fontFamily: FONT_FAMILY.primaryMedium,
    fontSize: 13,
    height: 35,
    color: COLORS.BLACK,
  },
  label: {
    fontFamily: FONT_FAMILY.primary,
    color: COLORS.GREY,
    position: 'absolute', // 绝对定位不占用输入框空间
    left: 10, // 和父容器水平内边距保持一致
  },
});

可根据实际设计稿调整位移、字体大小的数值,匹配预期视觉效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 11:54:02