React Native 鸿蒙跨平台开发:LayoutAnimation 实现鸿蒙端页面切换的淡入淡出过渡动画

目录

[一、RN 内置 LayoutAnimation 鸿蒙端核心特性](#一、RN 内置 LayoutAnimation 鸿蒙端核心特性)

核心定位

淡入淡出动画核心原理

[二、LayoutAnimation 核心 API 详解](#二、LayoutAnimation 核心 API 详解)

[2.1 核心调用方法](#2.1 核心调用方法)

[2.2 2 种动画配置方式](#2.2 2 种动画配置方式)

[方式 1:使用 RN 预设动画](#方式 1:使用 RN 预设动画)

[方式 2:自定义动画配置](#方式 2:自定义动画配置)

[2.3 动画生效的核心条件](#2.3 动画生效的核心条件)

三、鸿蒙实战:两大核心场景

一:组件显隐的淡入淡出动画

二:完整页面视图切换的淡入淡出动画

核心逻辑

四、鸿蒙端专属适配要点

鸿蒙端优化技巧

坑点


一、RN 内置 LayoutAnimation 鸿蒙端核心特性

核心定位

LayoutAnimation 是 React Native 内置的原生布局动画引擎 ,底层对接鸿蒙原生动画能力,专门用于实现「组件布局变化、显隐切换、视图替换」时的过渡动画,无需手动监听组件状态、无需逐帧控制动画参数,只需提前配置动画规则,RN 会自动为布局变化添加过渡效果,极简易用、高效优雅

淡入淡出动画核心原理

页面 / 组件切换的淡入淡出 ,本质是「组件的显示 / 隐藏」+「透明度从 0→1/1→0」+「布局自动过渡」的组合效果,LayoutAnimation 会自动监听组件的display/opacity/width/height等布局属性变化,为变化过程添加平滑的过渡动画,我们只需要提前配置好「动画类型、时长、缓动效果」,剩下的交给 RN 自动完成即可。

二、LayoutAnimation 核心 API 详解

LayoutAnimation的语法极其简洁,0 基础开发者只需掌握 3 个核心知识点,即可实现所有基础过渡动画,本次的淡入淡出效果,仅用到最核心的基础 API,无任何复杂语法,轻松掌握。

2.1 核心调用方法

javascript 复制代码
// 配置下一次布局变化时的动画规则,核心入口,一行代码生效
LayoutAnimation.configureNext(动画配置项);

核心作用 :提前声明「下一次页面布局发生变化时,要执行的动画规则」,当组件的显隐、宽高、位置等布局属性改变时,自动执行配置好的动画,这是LayoutAnimation的核心调用方式,没有之一。

2.2 2 种动画配置方式

方式 1:使用 RN 预设动画

RN 内置了多种开箱即用的预设动画配置 ,无需手动写任何动画参数,直接调用即可,本次实战的淡入淡出,就用预设动画完全满足需求,鸿蒙端完美支持,推荐新手优先使用。

javascript 复制代码
// 预设动画 - 常用3种(本次核心使用淡入淡出相关)
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); // 淡入淡出+缓入缓出(最常用,推荐)
LayoutAnimation.configureNext(LayoutAnimation.Presets.spring); // 弹性过渡+淡入淡出
LayoutAnimation.configureNext(LayoutAnimation.Presets.linear); // 线性过渡+淡入淡出
  • easeInEaseOut:核心推荐,动画速度「慢→快→慢」,过渡最丝滑,是页面切换淡入淡出的最佳选择;
  • linear:匀速过渡,动画节奏平稳;
  • spring:带弹性的过渡,适合强调型的组件切换。
方式 2:自定义动画配置

如果需要自定义「动画时长、淡入淡出速度」,可以传入自定义配置对象,所有参数均为可选,鸿蒙端完全支持,语法如下(按需调整即可):

javascript 复制代码
LayoutAnimation.configureNext({
  duration: 300, // 动画执行时长,单位ms,默认300ms,值越大动画越慢
  create: { type: LayoutAnimation.Types.easeInEaseOut, property: LayoutAnimation.Properties.opacity }, // 组件创建(显示)时的动画:透明度过渡
  update: { type: LayoutAnimation.Types.easeInEaseOut }, // 组件更新时的动画规则
  delete: { type: LayoutAnimation.Types.easeInEaseOut, property: LayoutAnimation.Properties.opacity }, // 组件销毁(隐藏)时的动画:透明度过渡
});

核心说明:opacity(透明度)是实现淡入淡出的核心属性,组件显示时透明度从 0→1(淡入),隐藏时从 1→0(淡出)。

2.3 动画生效的核心条件

LayoutAnimation监听布局变化 来执行动画的,想要让淡入淡出生效,必须满足一个简单条件:通过修改组件的 display/opacity/width/height 或 组件的挂载 / 卸载状态,触发布局变化 。本次实战中,我们用最简单的方式:通过useState控制组件的display属性(flex/none),实现组件的显示 / 隐藏,从而触发淡入淡出动画,这也是鸿蒙端页面切换最常用的方式。

三、鸿蒙实战:两大核心场景


一:组件显隐的淡入淡出动画

javascript 复制代码
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, LayoutAnimation } from 'react-native';

const FadeInOutBasic = () => {
  // 状态:控制组件是否显示
  const [isShow, setIsShow] = useState(true);

  // 点击切换显隐,核心:点击时提前配置动画规则
  const toggleShow = () => {
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
    // 修改状态,触发组件显隐,自动执行淡入淡出动画
    setIsShow(!isShow);
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>RN鸿蒙 · 基础淡入淡出动画</Text>
      
      <TouchableOpacity style={styles.btn} onPress={toggleShow}>
        <Text style={styles.btnText}>{isShow ? '点击淡出隐藏' : '点击淡入显示'}</Text>
      </TouchableOpacity>

      <View style={[styles.contentBox, { display: isShow ? 'flex' : 'none' }]}>
        <Text style={styles.contentText}>鸿蒙端淡入淡出动画演示</Text>
        <Text style={styles.contentDesc}>我是内容区域,显示时淡入,隐藏时淡出</Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#f7f8fa',
    paddingHorizontal: 20,
    gap: 25
  },
  title: {
    fontSize: 20,
    color: '#1a1a1a',
    fontWeight: '600'
  },
  btn: {
    width: '100%',
    height: 50,
    backgroundColor: '#007DFF',
    borderRadius: 8,
    justifyContent: 'center',
    alignItems: 'center'
  },
  btnText: {
    color: '#fff',
    fontSize: 16,
    fontWeight: '500'
  },
  contentBox: {
    width: '100%',
    height: 200,
    backgroundColor: '#fff',
    borderRadius: 8,
    justifyContent: 'center',
    alignItems: 'center',
    borderWidth: 1,
    borderColor: '#e5e5e5',
    gap: 10
  },
  contentText: {
    fontSize: 18,
    color: '#007DFF',
    fontWeight: '600'
  },
  contentDesc: {
    fontSize: 14,
    color: '#666'
  }
});

export default FadeInOutBasic;

二:完整页面视图切换的淡入淡出动画

核心逻辑
  1. 定义两个独立的页面视图(PageA、PageB),通过状态控制哪个视图显示;
  2. 点击切换按钮时,提前配置LayoutAnimation淡入淡出规则;
  3. 修改状态,触发视图的显隐切换,RN 自动为两个视图添加「淡出 + 淡入」的过渡动画;
  4. 切换过程平滑无生硬感,完全符合鸿蒙应用的交互体验。
javascript 复制代码
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, LayoutAnimation } from 'react-native';

const PageSwitchFade = () => {
  // 状态:控制当前显示的页面视图 A→true / B→false
  const [showPageA, setShowPageA] = useState(true);

  // 核心:页面切换方法,配置淡入淡出动画
  const switchPage = () => {
    // 配置自定义动画规则:调整时长为400ms,更丝滑的淡入淡出
    LayoutAnimation.configureNext({
      duration: 400, // 动画时长,值越大过渡越慢
      create: { type: LayoutAnimation.Types.easeInEaseOut, property: LayoutAnimation.Properties.opacity },
      update: { type: LayoutAnimation.Types.easeInEaseOut },
      delete: { type: LayoutAnimation.Types.easeInEaseOut, property: LayoutAnimation.Properties.opacity },
    });
    setShowPageA(!showPageA);
  };

  return (
    <View style={styles.container}>
      <TouchableOpacity style={styles.switchBtn} onPress={switchPage}>
        <Text style={styles.switchBtnText}>{showPageA ? '切换到页面B' : '切换到页面A'}</Text>
      </TouchableOpacity>

      <View style={[styles.pageBox, styles.pageA, { display: showPageA ? 'flex' : 'none' }]}>
        <Text style={styles.pageTitle}>页面视图 A</Text>
        <Text style={styles.pageDesc}>我是页面A,切换时执行淡出动画</Text>
      </View>

      <View style={[styles.pageBox, styles.pageB, { display: !showPageA ? 'flex' : 'none' }]}>
        <Text style={styles.pageTitle}>页面视图 B</Text>
        <Text style={styles.pageDesc}>我是页面B,切换时执行淡入动画</Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f7f8fa',
    padding: 20,
    gap: 20
  },
  switchBtn: {
    height: 50,
    backgroundColor: '#007DFF',
    borderRadius: 8,
    justifyContent: 'center',
    alignItems: 'center'
  },
  switchBtnText: {
    color: '#fff',
    fontSize: 16,
    fontWeight: '500'
  },
  pageBox: {
    flex: 1,
    borderRadius: 8,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 15
  },
  pageA: {
    backgroundColor: '#e8f4ff',
    borderColor: '#007DFF',
    borderWidth: 1
  },
  pageB: {
    backgroundColor: '#f0fff4',
    borderColor: '#00C853',
    borderWidth: 1
  },
  pageTitle: {
    fontSize: 22,
    color: '#1a1a1a',
    fontWeight: '600'
  },
  pageDesc: {
    fontSize: 14,
    color: '#666'
  }
});

export default PageSwitchFade;

四、鸿蒙端专属适配要点

鸿蒙端优化技巧

  1. 动画时长建议 :鸿蒙端的过渡动画,时长建议设置在 300~400ms 之间,这个区间的动画既丝滑又不会让用户等待,是鸿蒙官方推荐的动效时长;
  2. 样式圆角适配 :给页面 / 组件添加borderRadius:8,符合鸿蒙应用的圆角设计规范,动画过程中视觉效果更和谐;
  3. 按钮交互优化 :使用TouchableOpacity替代Button,鸿蒙端的按压反馈更柔和,贴合原生交互习惯;

坑点

  1. 动画不生效:配置动画的时机错误 ✔️ 正确做法:必须在修改状态(触发布局变化)之前调用 LayoutAnimation.configureNext(),RN 需要提前知道动画规则,才能为后续的布局变化添加动画;❌ 错误做法:先修改状态,再配置动画,此时布局变化已经完成,动画不会执行。

  2. 动画不生效:未触发布局变化 ✔️ 核心要求:LayoutAnimation只对布局属性变化 生效,必须通过修改display/opacity/width/height或组件挂载状态,触发布局变化;如果只是修改文字、颜色等非布局属性,动画不会执行。

  3. 多组件切换动画混乱 ✔️ 解决方案:多个组件切换时,只需调用一次LayoutAnimation.configureNext()即可,RN 会自动为所有布局变化的组件添加动画,无需重复调用。


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

相关推荐
哈__2 小时前
React Native 鸿蒙跨平台开发:Animated 实现鸿蒙端组件的上下滑动入场动画
react native·react.js·harmonyos
我要敲一万行2 小时前
前端文件上传
前端·javascript
要加油哦~2 小时前
算法 | 整理数据结构 | 算法题中,JS 容器的选择
前端·javascript·算法
一 乐10 小时前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
xkxnq12 小时前
第二阶段:Vue 组件化开发(第 16天)
前端·javascript·vue.js
wszy180913 小时前
顶部标题栏的设计与实现:让用户知道自己在哪
java·python·react native·harmonyos
Van_Moonlight13 小时前
RN for OpenHarmony 实战 TodoList 项目:空状态占位图
javascript·开源·harmonyos
xkxnq13 小时前
第一阶段:Vue 基础入门(第 15天)
前端·javascript·vue.js
BBBBBAAAAAi14 小时前
Claude Code安装记录
开发语言·前端·javascript