Lottie源码分析

2023-05-16

简介

我们使用Lottie的时候,最关键的类就是LottieAnimationView(继承自ImageView)和LottieDrawable(继承自Drawable),Lottie的描述文件最终会解析成一系列的Layer,然后在绘制的时候,根据不同的进度,绘制Layer的不同帧。

JSON描述文件

在分析源码之前,我们需要先认识一下,加载的json 文件的数据结构是怎样的。
比较重要的有三层,
assets,这个描述的是,图片资源的位置;
layers,这个描述的是,每个图层的相关信息;
shapes,这个描述的是,具体图层的动画元素相关信息。
-w1057

assets会解析成LottieImageAsset对象,
Layers层在渲染的时候,会被解析成以下几种类型中的一种。
-w760
shapes会被解析成ShapeGroup

动画文件的加载

整体的时序图:

整体的类图:

Lottie提供了各种数据源获取的API,根据数据源的不同选择不同的获取方式。
-w779
这里我们介绍一下,从assets下面获取解析json文件的流程。

public void setAnimation(final String animationName, final CacheStrategy cacheStrategy) {
this.animationName = animationName;
lottieDrawable.cancelAnimation();
cancelLoaderTask();
compositionLoader = LottieComposition.Factory.fromAssetFileName(getContext(), animationName,
new OnCompositionLoadedListener() {
@Override public void onCompositionLoaded(LottieComposition composition) {
      if (cacheStrategy == CacheStrategy.Strong) {
    strongRefCache.put(animationName, composition);
    } else if (cacheStrategy == CacheStrategy.Weak) {
        weakRefCache.put(animationName, new WeakReference<>(composition));
    }
    setComposition(composition);
    }
   });
  }

如上,先调用fromAssetFileName方法,会直接同步使用AssetManageropen方法,然后将InputStream流提供给FileCompositionLoader(继承自AsyncTask),在里面进行异步解析。最终会返回一个LottieComposition对象。

public class LottieComposition {
  //预合成的图层
  private final Map<String, List<Layer>> precomps = new HashMap<>();
  //图片资源
  private final Map<String, LottieImageAsset> images = new HashMap<>();
  //所有的Layer,带对应的ID
  private final LongSparseArray<Layer> layerMap = new LongSparseArray<>();
  //所有的layer,
  private final List<Layer> layers = new ArrayList<>();
  private final Rect bounds;
  private final long startFrame;
  private final long endFrame;
  private final int frameRate;
  private final float dpScale;
}

至此,就已经将json文件解析完成,接着会调用LottieDrawablesetComposition方法。进行一系列的初始化配置,包括速度、原始进度、colorFilter的设置、layer之间的关系等。

public boolean setComposition(LottieComposition composition) {
    if (this.composition == composition){return false;}
    clearComposition();
    this.composition = composition;
    //设置速度
    setSpeed(speed);
    updateBounds();
    //构建CompositionLayer,会将所有的Layer转换成为可以绘制的各种BaseLayer
    buildCompositionLayer();
    //处理colorFilter的设置
    applyColorFilters();
    //处理进度的设置
    setProgress(progress);
    //如果需要,怎在以上配置完成,开始执行动画
    if(playAnimationWhenCompositionAdded){
      playAnimationWhenCompositionAdded = false;
      playAnimation();
    }
      if(reverseAnimationWhenCompositionAdded) {
reverseAnimationWhenCompositionAdded = false;
      reverseAnimation();
    }
    return true;
  }

动画文件的渲染

其实就是将上面构建出来的各种BaseLayer进行对应的绘制。
-w577
当调用animator.start的时候,LottieDrawableonAnimationUpdate就会被回调,根据动画的进度,调用setProgress方法进行更新。

public void onAnimationUpdate(ValueAnimator animation) {
 if (systemAnimationsAreDisabled) {
    animator.cancel();
    setProgress(1f);
 } else {
    setProgress((float) animation.getAnimatedValue());
  }
}
public void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {
    this.progress = progress;
    if (compositionLayer != null) {
        compositionLayer.setProgress(progress);
    }
  }

而真正实现动画功能的,其实是CompositionLayer里面控制的。在这里会调用到每个BaseLayersetProgress,

public void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {
    super.setProgress(progress);
    progress -= layerModel.getStartProgress();
    for (int i = layers.size() - 1; i >= 0; i--) {
   layers.get(i).setProgress(progress);
    }
  }

而BaseLayer的setProgress会触发LottieDrawableinvalidateSelf方法,进行重新绘制。随着动画的不断执行,就会不断绘制对应进度的样式,形成动画。

    public void onValueChanged() {
        this.invalidateSelf();
    }
    private void invalidateSelf() {
    this.lottieDrawable.invalidateSelf();
    }

小结

整个流程其实就是:
1、通过LottieComposition.Factory获取对应数据源的json文件并解析成LottieComposition
2、调用LottieDrawablesetComposition,将所有的图层解析成对应的Layer,并构建出一个基础的CompositionLayer.
3、接着调用LottieDrawable的动画执行方法,触发BaseLayer的draw()方法不断执行,不断的绘制各个图层从而形成动画。

参考文章

1、https://www.imooc.com/article/29249

2、https://www.jianshu.com/p/e41c7d826324

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Lottie源码分析 的相关文章

  • pixhawk 源码分析-SPI驱动-MS5611

    最近学习了一下SPI的驱动软件 xff0c 在此将其进行总结 本文使用的代码为pixhawk 1 5 5版本的源码 源码下载地址 第一步函数入口 xff1a 老规矩 xff0c 所有px4的代码的函数入口都是在启动脚本中 xff0c 启动脚
  • LiveData源码分析

    首先还是以一个示例开始 xff1a MutableLiveData lt String gt liveString 61 new MutableLiveData lt gt liveString observe mOwner new Obs
  • PX4源码分析3:attitude_estimator_q(转载)

    原文链接 xff1a https blog csdn net zouxu634866 article details 79806948 include span class token operator lt span drivers sp
  • 【5G核心网】free5GC AMF源码分析

    free5gc AMF 源码分析 结构体 Sbi type Sbi struct Scheme string 96 yaml 34 scheme 34 96 RegisterIPv4 string 96 yaml 34 registerIP
  • 【containerd 源码分析】containerd image list 源码分析

    本文分析 containerd 列出所有镜像的分析过程 xff0c 包括 ctr image 命令行以及 containerd daemon 执行 过程 xff0c 也包含镜像 metadata xff0c content 等内容 1 执行
  • OVS Bond lacp源码分析

    近期项目中要使用Ovs bond接口 xff0c Ovs Bond 只有三种模式 xff1a balance tcp xff0c balance slb xff0c active backup 这三种模式的工作方式如下 xff1a 1 ac
  • Autoware源码分析——astar_avoid

    概要 本文是对autoware中waypoint planner功能包的相关文件组成和具体节点的分析 由于程序比较复杂 xff0c 我认为还存在一些不完整的地方 xff0c 之后也会继续分析 xff0c 继续更新 在看代码的过程中也学习了一
  • MAVROS 源码分析

    一 安装 MAVROS 利用机载计算机对 PX4 飞控进行 OFFBOARD 控制 xff0c 需要在机载计算机上安装 ROS 的 MAVROS 包 安装方式可以参考 PX4 开发者网站 xff0c 有二进制文件安装和源码安装两种方式 xf
  • PX4源码分析7_添加mavlink自定义消息

    一 自定义mavlink消息 xff1a 根据uorb消息 xff08 msg xff09 自定义mavlink消息 方法为利用mavlink generator工具在xml文件生成mavlink所需相应的头文件 二 发送自定义mavlin
  • Freertos 源码分析 队列queue

    队列queue xff08 零 xff09 队列的基础概念和形态 xff08 一 xff09 Freertos 队列 queue c FreeRTOS Kernel 10 4 6 include queue h Freertos队列模块包含
  • elasticjob 源码分析

    简介 elasticjob是基于quartz构建支持分片的分布式弹性可伸缩的job执行组件 zookeeper节点数据设计 job leader election latch instance 主节点的实例ID 临时节点 在节点选举成功后添
  • 反序列化漏洞攻击原理(Dubbo反序列化漏洞剖析)

    关联文章 给服务端发送自定义类实例序列化数据实现反序列化攻击 一 前言 最近大家都在讨论Dubbo反序列化漏洞问题 想必各个大V也都推送了相关文章 看了下各大文章差不多都是一个套路 两个步骤 第一步开始描述下Dubbo的反序列化漏洞 几乎都
  • mybatis 自动化处理 mysql 的json类型字段 终极方案

    文章目录 mybatis 自动化处理 mysql 的json类型字段 终极方案 why json 简介 mysql 建表 json 字段 添加1条json 数据 对应的java对象 JsonEntity mybatis 不使用 通用mapp
  • Mybatis执行过程源码解析

    使用Mybatis执行查询sql代码示例 SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder build Resources getResourceAsReade
  • Spring IOC容器初始化过程 源码分析

    本文主要记录Spring容器创建 源码分析过程 首先贴上一张时序图 好久没画 忘的差不多了 画的不好 可以凑合看一下 接下来 贴上一份测试代码 这里使用AnnotationConfigApplicationContext来初始化Spring
  • Spring创建Bean的全过程(一)

    Spring测试环境搭建 Spring模块概览 Spring中八大模块 黑色表示该模块的jar包 也就是组件 例如我们想要使用IOC容器 也就是绿色的CoreContainer 我们需要导入Beans Core Context SpEL s
  • Lottie系列一:介绍与使用

    文章目录 一 Lottie 二 Lottie起源 社区 2 1起源 2 2 社区 2 3 Why Lottie 效率 还原度高 体积 研发的优势 2 4 When Lottie 2 5 Lottie不支持的效果 2 6 官方Demo和在线预
  • android 休眠唤醒机制分析(一) — wake_lock

    Android的休眠唤醒主要基于wake lock机制 只要系统中存在任一有效的wake lock 系统就不能进入深度休眠 但可以进行设备的浅度休眠操作 wake lock一般在关闭lcd tp但系统仍然需要正常运行的情况下使用 比如听歌
  • IDEA国际化资源Key无法全局重命名的解决方案

    一 前言 最近在开发中使用到了HibernateValidator进行入参校验以及错误消息的国际化支持 大家应该都知道在使用HibernateValidator进行校验的时候 我们只需在需要在校验的变量上添加相应的注解 同时在message
  • 如何在数据加载期间 IsBusy 为 true 时至少显示一次 Lottie 动画?

    On my Xamarin Forms 项目 我想显示一个洛蒂动画 during API调用或期间加载网站 in a WebView 为此 我限制了IsVisible的财产洛蒂动画 to the IsBusy我的财产视图模型 这个效果很好

随机推荐

  • 这个交互也太炸裂了趴

    动画是为一个app创造出色用户体验的重要组成部分 它的关键挑战是向用户解释应用程序的逻辑 xff0c 但是常见的错误是鲁莽地使用动画 xff0c 从而否定了改善用户体验的整个观点 为了使应用出色而不仅仅是出色或平庸 xff0c 动画必须正确
  • 在ES6的语法中如何给数组去重

    这是从数组中筛选出重复项并仅返回唯一值的三种方法 我最喜欢使用Set xff0c 因为它最短 xff0c 最简单 xff1b set Set是ES6中引入的新数据对象 因为Set仅允许您存储唯一值 传递数组时 xff0c 它将删除所有重复值
  • 笔记啊啊啊啊

    判断某个字符串中是否其他某些字符串 span class token keyword const span deviceName span class token operator 61 span e span class token pu
  • android 高德地图之poi搜索功能的实现

    二话不多说 先看效果 这个功能我是用Fragmentdialog里面做的 也遇到不少坑 第一 就是设置背景的drawable为纯白色导致键盘弹出的时候 recyclerview的布局被顶上去导致出现白色布局 有点扎眼 最后改成了设置为和背景
  • android之 h5调用系统相机和相册并显示

    先上html界面的代码 放在assets里面就可以了 我也不太会html 所以随便写了点 span class hljs doctype lt doctype html gt span span class hljs tag lt span
  • 深坑之Webview,解决H5调用android相机拍照和录像

    最近在开发过程中遇到一个问题 主要是调用第三方的实名认证 需要拍照和录像 办过支付宝大宝卡和腾讯的大王卡的都知道这玩意 办卡的时候就需要进行实名认证 人脸识别 本来第三方平台 xxx流量公司 说的是直接用WebView加载这个H5界面就完事
  • rxjava2定时器每秒请求一次数据

    项目进行的过程中有个需求是在20秒内每秒请求一次数据 xff0c 请求成功的json中有个字段 xff0c 如果有这个字段代表请求成功 xff0c 如果没有则继续请求 xff0c 直到20秒结束 xff0c 20秒结束则失败 本来最开始采用
  • Flutter导航栏实现

    学了几天的flutter 似乎有点感觉了 今天来上手搞一个导航栏 实现类似android里面的ViewPager 43 Fragment的效果 二话不说直接上代码 import 39 package flutter material dar
  • SpringBoot 日志文件

    1 日志的作用2 日志怎么用3 自定义日志打印3 1 得到日志对象3 2 使用日志对象提供的方法打印日志3 3 日志格式说明 4 日志级别4 1 日志级别分类4 2 日志级别的配置 5 日志持久化6 更简单的实现自定义日志的打印6 1 准备
  • Flutter实现滑动头部折叠切换tab

    主要使用到NestedScrollView和SliverAppBar 先看效果 xff1a 代码如下 xff1a import 39 package flutter material dart 39 class ActPage extend
  • ubuntu apt-get 默认下载路径

    使用apt get install 命令时默认下载到 var cache apt archives路径下 xff0c sudo apt get clean命令可以删除该路径下的下载的deb包 例如仅下载ssh xff0c 不安装 xff1a
  • vscode 离线安装ssh

    首先打开官方插件地址 xff1a https marketplace visualstudio com VSCode 然后输入ssh 下载这两个插件 xff1a 安装这两个插件 xff1a 这样便在windows下安装成功了ssh 接下来需
  • windows BDA driver (abstract)

    AVStream is a Microsoft provided multimedia class driver that supports video only streaming and integrated audio video s
  • Ubuntu平台采用Qemu搭建ARM虚拟机环境

    1 Busybox编译 下载代码 xff1a 查看Busybox Source Control网站 xff0c 有代码控制说明 xff0c 我们采用git clone下载代码 xff1a BusyBox git clone git busy
  • 详细解读Python豆瓣电影Top250网页爬取(主要对re的运用&excel保存数据)//包括对库的简介

    python里面有很多操作都类似于c语言 xff0c 这里在爬取时主要需要注意用到的是for循环语句和各种库 个人认为python中主要还是对库的运用比较占大比例 xff08 这里的软件版本是PyCharm 2020 3 2 x64 xff
  • 在android中配置 slf4j + log4j 日志记录框架

    需求 xff1a 在项目开发中 xff0c 需要记录 操作日志 起初自己写了个简单的日志记录文本写入到文本的方法 xff0c 后来随着项目的膨胀 xff0c 需要考虑更多的操作 xff0c 开始考虑性能问题 实现 xff1a 考虑使用 sl
  • ZipInputStream解压远程文件报错,java.lang.IllegalArgumentException: MALFORMED[1]

    我遇到的问题是报的这个错java lang IllegalArgumentException MALFORMED 1 at java util zip ZipCoder toString ZipCoder java 65 不是 java l
  • OAuth2.0接百度平台进行授权

    百度开发文档 xff1a https openauth baidu com doc regdevelopers html 1 注册开发者账号并创建一个应用 2 创建应用后 xff0c 获取API Key和Secret Key 3 创建一个S
  • Spring 中最常用的 11 个扩展点

    1 自定义拦截器 spring mvc拦截器根spring拦截器相比 xff0c 它里面能够获取HttpServletRequest和HttpServletResponse等web对象实例 spring mvc拦截器的顶层接口是 xff1a
  • Lottie源码分析

    简介 我们使用Lottie的时候 xff0c 最关键的类就是LottieAnimationView 继承自ImageView 和LottieDrawable 继承自Drawable xff0c Lottie的描述文件最终会解析成一系列的La