目录

一、LayoutAnimation 模心说明

1.1 LayoutAnimation 核心定位

1.2 LayoutAnimation 核心原理

1.3 鸿蒙端支持的预设动画

二、基础语法

步骤 1:引入 LayoutAnimation

步骤 2:配置动画 + 触发布局变化

三、鸿蒙端表单元素动态添加动画

效果

四、鸿蒙端专属适配要点

1. 必须 “先配置动画,再修改 state”

2. 用 “immutable 方式更新 state”

3. 鸿蒙端无需额外配置


一、LayoutAnimation 模心说明

1.1 LayoutAnimation 核心定位

RN 内置模块,鸿蒙端原生支持:无需 npm/yarn 安装,直接调用,鸿蒙 2.0 + 全版本兼容,无工程配置成本;✅ “自动布局动画” 工具:专门处理 “组件新增 / 删除 / 位置变化” 时的布局过渡动画,无需手动写 Animated 的插值、动画值,一行代码实现动画;✅ 0 基础友好:核心 API 仅 1 个(LayoutAnimation.configureNext()),预设多种动画效果,无需掌握动画算法;✅ 高性能:动画由鸿蒙原生线程执行,不占用 JS 主线程,在鸿蒙手机 / 平板上运行丝滑,无掉帧、卡顿问题;✅ 场景聚焦:完美适配 “动态表单(新增输入框)、列表动态增删、弹窗展开 / 收起” 等鸿蒙端高频布局变化场景,本次重点实现表单元素动态添加动画

1.2 LayoutAnimation 核心原理

LayoutAnimation 的逻辑极其简单,是 “配置动画规则 → 触发布局变化 → 自动执行动画” 的三步流程:

  1. 配置动画:通过 LayoutAnimation.configureNext() 告诉 RN “接下来的布局变化要使用什么动画”(比如弹簧、线性过渡);
  2. 触发布局变化:修改组件的 state(比如给表单元素数组新增一项),让 RN 重新渲染布局;
  3. 自动动画:RN 检测到布局变化后,自动对 “新增 / 删除 / 移动的组件” 应用之前配置的动画,实现丝滑过渡。

1.3 鸿蒙端支持的预设动画

LayoutAnimation 内置了 3 种鸿蒙端完美支持的预设动画,无需自定义,直接调用即可,覆盖 99% 的开发需求:

预设动画 效果描述 鸿蒙端适配 适用场景
LayoutAnimation.Presets.spring 弹性过渡动画(轻微回弹,最丝滑) ✅ 完美支持 表单元素、列表项动态添加
LayoutAnimation.Presets.linear 匀速过渡动画(平稳无回弹) ✅ 完美支持 简单布局变化、弹窗展开
LayoutAnimation.Presets.easeInEaseOut 缓入缓出动画(先慢后快再慢) ✅ 完美支持 卡片、模块的动态显示 / 隐藏

二、基础语法

LayoutAnimation 是 RN 中学习成本最低的动画工具,0 基础只需掌握 2 个核心步骤,即可实现所有布局变化动画:

步骤 1:引入 LayoutAnimation

import { LayoutAnimation } from 'react-native';

步骤 2:配置动画 + 触发布局变化

核心逻辑先调用 LayoutAnimation.configureNext() 配置动画,再修改 state 触发布局变化(顺序不能错,否则动画不生效)。

// 1. 初始化state:存表单输入框列表
const [formItems, setFormItems] = useState(['输入框1']);

// 2. 点击“添加”按钮的事件
const addFormItem = () => {
  // 步骤A:配置动画(用弹簧预设,鸿蒙端推荐)
  LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);
  
  // 步骤B:修改state,新增输入框(必须是immutable更新,比如concat)
  setFormItems(prev => [...prev, `输入框${prev.length + 1}`]);
};

三、鸿蒙端表单元素动态添加动画

以下是鸿蒙端表单动态添加输入框的完整实战案例,包含 “表单布局、添加按钮、动态元素动画、鸿蒙风格样式”,代码零报错、真机 + 模拟器双端适配,直接复制即可运行。

import React, { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, StyleSheet, LayoutAnimation } from 'react-native';

const LayoutAnimationFormDemo = () => {
  const [formItems, setFormItems] = useState([{ id: 1, placeholder: '请输入内容' }]);

  const addFormItem = () => {
    LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);

    const newItem = {
      id: formItems.length + 1,
      placeholder: `请输入内容${formItems.length + 1}`
    };
    setFormItems(prevItems => [...prevItems, newItem]);
  };

  return (
    <View style={styles.container}>
      <Text style={styles.pageTitle}>鸿蒙端动态表单添加动画</Text>

      <View style={styles.formContainer}>
        {formItems.map((item) => (
          <View key={item.id} style={styles.inputWrap}>
            <TextInput
              style={styles.input}
              placeholder={item.placeholder}
              placeholderTextColor="#999"
            />
          </View>
        ))}
      </View>

      <TouchableOpacity
        style={styles.addBtn}
        onPress={addFormItem}
        activeOpacity={0.7}
      >
        <Text style={styles.btnText}>+ 添加输入框</Text>
      </TouchableOpacity>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#f7f8fa',
    paddingHorizontal: 20,
    gap: 20
  },
  pageTitle: {
    fontSize: 20,
    color: '#1a1a1a',
    fontWeight: '600',
    marginBottom: 10
  },
  formContainer: {
    width: '90%',
    gap: 15
  },
  inputWrap: {
    backgroundColor: '#fff',
    borderRadius: 8,
    padding: 10,
    shadowColor: '#000',
    shadowOpacity: 0.08,
    shadowRadius: 4
  },
  input: {
    height: 45,
    paddingHorizontal: 10,
    fontSize: 16,
    color: '#333',
    borderWidth: 1,
    borderColor: '#e0e0e0',
    borderRadius: 6
  },
  addBtn: {
    width: '90%',
    height: 50,
    backgroundColor: '#007DFF',
    borderRadius: 8,
    justifyContent: 'center',
    alignItems: 'center',
    marginTop: 10
  },
  btnText: {
    fontSize: 16,
    color: '#fff',
    fontWeight: '500'
  }
});

export default LayoutAnimationFormDemo;

效果

点击 “+ 添加输入框” 按钮后:

  1. 新的输入框会以弹性动画从下方 “滑入 + 渐显”(鸿蒙原生丝滑效果);
  2. 已有输入框会自动平滑调整位置,无生硬跳动;
  3. 动画由鸿蒙原生线程驱动,在低配鸿蒙设备上也无卡顿。

四、鸿蒙端专属适配要点

LayoutAnimation 在鸿蒙端的使用极其简单,但需注意 3 个核心适配细节,避免动画不生效或效果异常:

1. 必须 “先配置动画,再修改 state”

这是 LayoutAnimation 的铁律,顺序不能颠倒:

  • 错误顺序:先修改 state,再配置动画 → 动画不生效;
  • 正确顺序:先调用 LayoutAnimation.configureNext(),再用 setState 更新布局 → 动画正常触发。

2. 用 “immutable 方式更新 state”

修改表单列表时,必须使用不修改原数组的方式(比如展开运算符、concat),不能用 push 修改原数组:

  • 错误:formItems.push(newItem); setFormItems(formItems);(RN 检测不到数组变化,无动画);
  • 正确:setFormItems(prev => [...prev, newItem]);(immutable 更新,RN 能检测到变化,触发动画)。

3. 鸿蒙端无需额外配置

  • 无需开启 “原生驱动”:LayoutAnimation 本身就是原生级动画,鸿蒙端默认支持;
  • 无需权限:动画属于基础交互功能,无需在鸿蒙工程的 config.json 中配置任何权限;
  • 模拟器支持:LayoutAnimation 在鸿蒙模拟器上可以正常预览动画效果,无需真机即可调试。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐