HarmonyOS 鸿蒙Next中Lottie动画

HarmonyOS 鸿蒙Next中Lottie动画 求最新的鸿蒙Lottie动画使用全流程🙏

6 回复

更多关于HarmonyOS 鸿蒙Next中Lottie动画的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


项目中正在使用的代码复制给你

import lottie, { AnimationItem } from "@ohos/lottie";

@Preview
@Component
export struct LottieView {
  name = "sleeping_2"
  private animateItem: AnimationItem | null = null;
  private renderingSettings: RenderingContextSettings = new RenderingContextSettings(true)
  private canvasRenderingContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.renderingSettings)
  private animateItem2: AnimationItem | null = null;

  aboutToAppear(): void {
    console.info('aboutToAppear');

    lottie.destroy('aboutToAppear')
    this.animateItem2 = lottie.loadAnimation({
      container: this.canvasRenderingContext,
      renderer: 'canvas', // canvas 渲染模式
      loop: true,
      autoplay: true,
      name: this.name,
      contentMode: 'Contain',
      path: "pages/common/lottie/"+this.name+".json",
      // path: "common/lottie/data_rawfile.json"
      // path: "common/lottie/data_base64.json"
    })
  }

  build() {
    Column() {
      Stack() {
        Canvas(this.canvasRenderingContext)
          .width('100%')
          .height('100%')
          //.backgroundColor(Color.Gray)
          .onReady(() => {
            this.animateItem2?.resize();
          })
          .onDisAppear(() => {
            // 组件移除时,可销毁动画资源
            lottie.destroy(this.name);
          })
      }
    }
  }

}

使用示例:

import lottie, { AnimationItem } from '[@ohos](/user/ohos)/lottie';

@Entry
@Component
struct Index {
  // 构建上下文
  private renderingSettings: RenderingContextSettings = new RenderingContextSettings(true);
  private canvasRenderingContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.renderingSettings);
  private animateItem: AnimationItem | null = null;
  private animateName: string = 'animation'; 

  // 页面销毁时释放动画资源
  aboutToDisappear(): void {
    console.info('aboutToDisappear');
    lottie.destroy();
  }

  build() {
    Row() {
      // 关联画布
      Canvas(this.canvasRenderingContext)
        .width(200)
        .height(200)
        .backgroundColor(Color.Gray)
        .onReady(() => {
          // 加载动画
          if (this.animateItem != null) {
            // 可在此生命回调周期中加载动画,可以保证动画尺寸正确
            this.animateItem?.resize();
          } else {
            // 抗锯齿的设置
            this.canvasRenderingContext.imageSmoothingEnabled = true;
            this.canvasRenderingContext.imageSmoothingQuality = 'medium';
            this.loadAnimation();
          }
        })
    }
  }

  loadAnimation() {
    this.animateItem = lottie.loadAnimation({
      container: this.canvasRenderingContext,
      renderer: 'canvas', // canvas 渲染模式
      loop: true,
      autoplay: false,
      name: this.animateName,
      contentMode: 'Contain',
      path: 'common/animation.json',
    })
    // 因为动画是异步加载,所以对animateItem的操作需要放在动画加载完成回调里操作
    this.animateItem.addEventListener('DOMLoaded', (args: Object): void => {
      this.animateItem.changeColor([225, 25, 100, 1]);
      this.animateItem.play();
    });
  }

  destroy() {
    this.animateItem.removeEventListener('DOMLoaded');
    lottie.destroy(this.animateName);
    this.animateItem = null;
  }
}

参考文档:OpenHarmony三方库中心仓

看你选用哪个 lottie 库来用了

推荐使用 lottie-turbo:声明式调用更加简洁,支持并行加载、内存缓存、子线程渲染,性能优化30%+,多动画/复杂动画场景下UI界面更流畅。

[@ohos/lottie-turbo-OpenHarmony三方库中心仓](https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Flottie-turbo)

[@ohos/lottie-OpenHarmony三方库中心仓](https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Flottie)

下载安装

ohpm install [@ohos](/user/ohos)/lottie-turbo

快速上手

简易示例

import { LottieController, LottieView } from '[@ohos](/user/ohos)/lottie-turbo';

@Entry
@Component
struct Load {
    private controller: LottieController = new LottieController();

    build() {
        Column() {
            LottieView({
                lottieId: "lottie1", //动画id,需要保证唯一性
                loop: true, //是否循环播放,非必须,默认为true
                autoplay: true, //是否自动播放,非必须,默认为true
                autoSkip: true, //不可见时是否自动跳过渲染,非必须,默认为true
                path: $rawfile('common/lottie/grunt.json'), //通过rawfie文件播放
                // path: "https://cdn.lottielab.com/l/7Zgk9iuQxmZ3tD.json", //通过uri播放
                // 通过动画json的字符串播放(string类型),该属性优先级 > path
                // animationData: '{"v":"5.5.2","fr":60,"ip":0,"op":60,"w":512,"h":512,"ddd":0,"assets":[{"id":"Aa19853e5c3b98a7b8dde147916d26f78","h":114,"w":114,"u":"","p":"https://raw.gitcode.com/openharmony-sig/lottie_turbo/blobs/205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b/startIcon.png","e":1}],"layers":[{"ddd":0,"ty":2,"sr":1,"ks":{"a":{"k":[0,0],"a":0},"p":{"k":[{"t":0,"s":[0,0,0],"i":{"x":[0.75],"y":[0.75]},"o":{"x":[0.25],"y":[0.25]}},{"t":60,"s":[400,400],"i":{"x":[0.75],"y":[0.75]},"o":{"x":[0.25],"y":[0.25]}}],"a":1},"s":{"k":[100,100],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0},"sk":{"k":0,"a":0},"sa":{"k":0,"a":0}},"ao":0,"ip":0,"op":60,"st":0,"bm":0,"ind":0,"refId":"Aa19853e5c3b98a7b8dde147916d26f78"}]}',
                controller: this.controller, //lottie动画控制器
            })
                .width('50%')
                .height(160)
                .backgroundColor(Color.Gray)
                .onClick(() => {
                    this.controller.togglePause(); //控制动画播放暂停
                })
        }
        .height('100%')
            .width('100%')
    }
}

补充示例

import { LottieView, LottieController, LottieListener, lottie } from '[@ohos](/user/ohos)/lottie-turbo';

@Entry
@Component
struct Index {
  private controller: LottieController = new LottieController(); //动画控制器
  // 事件监听器
  private listener: LottieListener = new LottieListener({
    onEnterFrame: () => { //开始渲染帧回调
      this.updateAllStates()
    },
    onLoopComplete: () => { //动画循环播放一轮完成时
      console.info("lottie complete");
      this.playCount = this.controller?.playCount;
      this.totalPlayedCount += 1;
    },
    onComplete: () => { //动画播放结束时调用
      this.log += "lottie1 event complete\r\n"
    },
    onDestroy: () => {  //动画删除后回调
      console.info("lottie destroy");
    },
    onDOMLoaded: () => { //动画加载完成,播放之前触发回调
      console.info("lottie DOMLoaded");
    },
    onDataReady: () => { //动画数据初始化完成时调用
      this.log += "lottie1 event data_ready\r\n"
    },
  })

  build() {
  ...
      LottieView({
            loop: true, //是否循环
            autoplay: true, //自动播放
            autoSkip: true, //不可见时是否自动跳过渲染
            lottieId: "lottie1" + this.getUniqueId(), //设置唯一id
            contentMode: 'Contain', //填充模式
            path: $rawfile('common/lottie/animation.json'), //动画路径
            frameRate: 30, //播放帧率,1-120Hz
            controller: this.controller,  //动画控制器
            initialSegment: [30, 150], //初始化动画资源播放时的整体帧范围
            listener: this.listener, //监听事件容器
            useCache: true, //是否使用缓存
            setImageAssetDelegate: [["refid", "uri" ]]//替换图片资源文件,支持Base64和uri
          })
      Button("全局控制")
        .onClick(() => {
           lottie.play(); //全局播放
           lottie.pause(); //全局暂停
           lottie.stop(); //全局停止
           lottie.destroy(); //全局暂停
           lottie.togglePause();//全局切换暂停/播放
           lottie.setSpeed(1); //设置全局播放速度
           lottie.setDirection(1); //设置全局播放方向  1代表正向 -1代表方向
           lottie.setFrameRate(30);//全局设置播放帧率
           lottie.clearFileCache("");//清除单个文件缓存  不传参数为清除所有文件缓存
           lottie.clearCache();//清除内存缓存
           lottie.resizeCache(10, 10 * 1024 * 1024);//重置内存缓存大小
           lottie.resizeFileCache(10, 1024*1024);//重置文件缓存大小
           lottie.removeCache("path")//通过key删除内存缓存
        })
      Button("单个控制")
        .onClick(() => {
           this.controller.play(); //播放
           this.controller.stop(); //停止
           this.controller.pause(); //暂停
           this.controller.destroy(); //销毁
           this.controller.setSpeed(1); //设置播放速度
           this.controller.goToAndPlay(250,true); //跳转到250帧并播放,false单位为ms
           this.controller.goToAndStop(250,true); //跳转到250帧并停止,false单位为ms
           this.controller.setDirection(1); //设置播放方向  1代表正向 -1代表方向
           this.controller.setSegment(350, 0); //限定动画资源播放时的整体帧范围
           this.controller.setSubframe(true); //设置是否插帧播放,默认为true
           this.controller.playSegments([[5,15],[20,30]],false);//下次播放按照片段设置播放,tru立即生效
           this.controller.changeColor("**", [255, 0, 0, 1]); //按照图层名称,修改RGBA动画颜色
           this.controller.togglePause() //切换暂停/播放
           this.controller.setFrameRate(30) //设置播放帧率
           this.controller1.setContentMode("Contain"); //设置填充模式,支持Fill,Cover,Top,Bottom,Contain
           this.controller.reload({
                path: "https://kjstorage.360buyimg.com/cms-file/1_eec97231.zip"
           })
           //添加监听事件
           this.controller.addEventListener('drawFrame', (): void => {
               this.log += "add lottie event " + eventName + "\r\n"
           });
           this.controller.removeEventListener(‘drawFrame’); //移除监听事件
           this.controller.triggerEvent("drawFrame"); //强制触发回调
           //
        })                
   ...      
  }   
  
  // 默认在LottieView组件销毁时自动触发销毁
  aboutToDisappear(): void {
    
  } 
}

鸿蒙Next中Lottie动画通过ArkUI框架的Lottie组件实现。该组件支持加载JSON格式的动画文件,提供自动播放、循环控制、速度调整等基础功能。支持通过属性设置动画进度、尺寸和交互行为。可通过数据绑定动态控制动画状态,与鸿蒙声明式UI无缝集成。性能经过优化,适用于界面动效、加载动画等场景。

在HarmonyOS Next中,Lottie动画的使用流程如下:

  1. 添加依赖:在模块的build.gradle文件中添加Lottie库依赖:

    dependencies {
        implementation 'com.airbnb.android:lottie:6.0.0'
    }
    
  2. 导入JSON动画文件:将Lottie JSON动画文件(例如animation.json)放置在resources/base/media/目录下。

  3. XML布局中添加LottieAnimationView

    <com.airbnb.lottie.LottieAnimationView
        android:id="@+id/lottie_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:lottie_fileName="animation.json"
        app:lottie_loop="true"
        app:lottie_autoPlay="true" />
    
  4. 代码控制(可选):在ArkTS/Java代码中动态控制动画:

    let lottieView = findComponentById<LottieAnimationView>(this, 'lottie_view');
    lottieView.playAnimation(); // 播放
    lottieView.pauseAnimation(); // 暂停
    lottieView.setProgress(0.5); // 设置进度
    
  5. 性能优化:对于复杂动画,建议启用硬件加速,并在不需要时及时释放资源。

注意:确保使用的Lottie版本与HarmonyOS Next兼容,JSON文件需符合Lottie规范。

回到顶部