当前位置:   article > 正文

Android -Lottie加载动画喂饭指南_lottie 动态加载资源

lottie 动态加载资源

什么是Lottie

简单的说,Lottie就是airbnb开源的一个使用json文件快速加载动画且支持多平台的库。

更多介绍请查看官网。官网地址:https://airbnb.design/lottie/

怎么使用Lottie

在项目的build.gradle文件中直接添加依赖:

  1. dependencies {
  2. implementation 'com.airbnb.android:lottie:$lottieVersion'
  3. }

这里需要注意的是,lottie最低支持API 16,Lottie版本2.8.0及其以上升级了androidx,本篇文章主要介绍2.7.0的使用方法。

关于最新版本请查看lottie的GitHub地址:https://github.com/airbnb/lottie-android,现在最新版本号已经到了3.4.0,版本更新有些快。

加载动画方式

使用资产文件(src/main/assets)

将json文件和image文件夹放到资产文件下方,代码加载:

  1. lottieAnimationView.setImageAssetsFolder(imagesPath);
  2. lottieAnimationView.setAnimation(jsonPath);
  3. lottieAnimationView.playAnimation();

或者只使用json文件可在xml文件中直接加载:

  1. <com.airbnb.lottie.LottieAnimationView
  2. android:id="@+id/lottieAnimationView"
  3. android:layout_width="wrap_content"
  4. android:layout_height="wrap_content"
  5. app:lottie_fileName="test.json"
  6. app:lottie_loop="true"
  7. app:lottie_autoPlay="true" />

使用服务器json文件

  1. LottieComposition.Factory
  2. .fromJson(getResources(), json, new OnCompositionLoadedListener() {
  3. @Override
  4. public void onCompositionLoaded(LottieComposition composition) {
  5. lottieAnimationView.setComposition(composition);
  6. lottieAnimationView.playAnimation();
  7. }
  8. });

使用服务器上zip文件

1、直接网络加载:

  1. lottieAnimationView.setAnimationFromUrl(ZIPURL);
  2. lottieAnimationView.playAnimation();

2、下载zip文件本地解压加载

关于文件下载这里就不多介绍了,网络上有很多介绍。下载zip文件之后我们要进行解压缩:

  1. /**
  2. * 解压assets的zip压缩文件到指定目录(包含子目录)
  3. * @param zipFileName 压缩文件名
  4. * @param outputDirectory 输出目录
  5. * @throws IOException
  6. */
  7. public static void unZip(String zipFileName, String outputDirectory) {
  8. ZipFile zipFile = null;
  9. try {
  10. zipFile = new ZipFile(zipFileName);
  11. Enumeration e = zipFile.entries();
  12. ZipEntry zipEntry;
  13. File dest = new File(outputDirectory);
  14. dest.mkdirs();
  15. while (e.hasMoreElements()) {
  16. zipEntry = (ZipEntry) e.nextElement();
  17. String entryName = zipEntry.getName();
  18. InputStream in = null;
  19. FileOutputStream out = null;
  20. try {
  21. if (zipEntry.isDirectory()) {
  22. String name = zipEntry.getName();
  23. name = name.substring(0, name.length() - 1);
  24. File f = new File(outputDirectory + File.separator
  25. + name);
  26. f.mkdirs();
  27. } else {
  28. int index = entryName.lastIndexOf("\\");
  29. if (index != -1) {
  30. File df = new File(outputDirectory + File.separator
  31. + entryName.substring(0, index));
  32. df.mkdirs();
  33. }
  34. index = entryName.lastIndexOf("/");
  35. if (index != -1) {
  36. File df = new File(outputDirectory + File.separator
  37. + entryName.substring(0, index));
  38. df.mkdirs();
  39. }
  40. File f = new File(outputDirectory + File.separator
  41. + zipEntry.getName());
  42. in = zipFile.getInputStream(zipEntry);
  43. out = new FileOutputStream(f);
  44. int c;
  45. byte[] by = new byte[1024];
  46. while ((c = in.read(by)) != -1) {
  47. out.write(by, 0, c);
  48. }
  49. out.flush();
  50. }
  51. } catch (IOException ex) {
  52. ex.printStackTrace();
  53. Log.e("unZip", "解压失败:" + ex.toString());
  54. UnAnimationZipFinshEvent.post("Zip.class", false,null);
  55. } finally {
  56. if (in != null) {
  57. in.close();
  58. }
  59. if (out != null) {
  60. out.close();
  61. }
  62. }
  63. }
  64. Log.e("unZip", "解压成功");
  65. UnAnimationZipFinshEvent.post("Zip.class", true,outputDirectory);
  66. deleteDir(new File(zipFileName));
  67. } catch (IOException ex) {
  68. ex.printStackTrace();
  69. Log.e("unZip", "解压失败:" + ex.toString());
  70. UnAnimationZipFinshEvent.post("Zip.class", false,null);
  71. } finally {
  72. if (zipFile != null) {
  73. try {
  74. zipFile.close();
  75. } catch (IOException ex) {
  76. ex.printStackTrace();
  77. }
  78. }
  79. }
  80. }
  1. /**
  2. * 删除整个文件夹 或者 文件
  3. */
  4. private static void deleteDir(File file) {
  5. if (!file.exists()) {
  6. return;
  7. }
  8. if (file.isDirectory()) {
  9. File[] childFiles = file.listFiles();
  10. if (childFiles == null || childFiles.length == 0) {
  11. file.delete();
  12. }
  13. for (File childFile : childFiles) {
  14. deleteDir(childFile);
  15. }
  16. }
  17. file.delete();
  18. }

使用Lottie加载本地动画资源:

  1. /**
  2. * 加载本地动画资源
  3. * @param lottieAnimationView 展示动画view
  4. * @param imagesPath 本地动画资源图片地址
  5. * @param dataPath 本地动画资源json数据地址
  6. */
  7. public static void loadLottie(LottieAnimationView lottieAnimationView,String imagesPath,String dataPath){
  8. // 动效图片资源
  9. final File imagesFiles = new File(imagesPath);
  10. // data.json路径
  11. final File jsonFile = new File(dataPath);
  12. if (!jsonFile.exists() || !imagesFiles.exists()) {
  13. Log.e("lottieUtils", "动画资源不存在");
  14. return;
  15. }
  16. try {
  17. FileInputStream fis = new FileInputStream(jsonFile);
  18. final String absolutePath = imagesFiles.getAbsolutePath();
  19. // 开启硬件加速
  20. lottieAnimationView.useHardwareAcceleration(true);
  21. // 设置动画文件夹代理类
  22. lottieAnimationView.setImageAssetDelegate(new ImageAssetDelegate() {
  23. @Override
  24. public Bitmap fetchBitmap(LottieImageAsset asset) {
  25. BitmapFactory.Options opts = new BitmapFactory.Options();
  26. opts.inScaled = true;
  27. Bitmap bitmap = null;
  28. try {
  29. bitmap = BitmapFactory.decodeFile(absolutePath + File.separator + asset.getFileName(), opts);
  30. } catch (Exception e) {
  31. e.printStackTrace();
  32. }
  33. return bitmap;
  34. }
  35. });
  36. // 设置动画
  37. LottieComposition.Factory.fromInputStream(fis, new OnCompositionLoadedListener() {
  38. @Override
  39. public void onCompositionLoaded(@Nullable LottieComposition composition) {
  40. lottieAnimationView.setComposition(composition);
  41. lottieAnimationView.playAnimation();
  42. try {
  43. fis.close();
  44. } catch (IOException e) {
  45. e.printStackTrace();
  46. }
  47. }
  48. });
  49. } catch (FileNotFoundException e) {
  50. e.printStackTrace();
  51. }
  52. }

另外,我们在下载动画资源到本地之后,手机相册会自动扫描到,这样相册里会有很多动画分解的图片,一是对于相册展示不太好,二是用户有可能会删除某张分解动画的图片。所以,这里简单介绍下一下2种避免图片自动扫描到相册的方法:

1、创建隐藏文件夹存放动画资源,只需要在文件名前加. (例如:.lottie)。

2、在存储动画资源的文件的文件夹下添加.nomedia 文件,告诉系统改文件夹下没有多媒体 文件。

常用API

成功和失败监听

  1. LottieCompositionFactory.fromUrl(this,ZIPURL)
  2. .addFailureListener(new LottieListener<Throwable>() {
  3. @Override
  4. public void onResult(Throwable result) {
  5. // TODO: 添加加载失败逻辑
  6. }
  7. }).addListener(new LottieListener<LottieComposition>() {
  8. @Override
  9. public void onResult(LottieComposition result) {
  10. lottieAnimationView.setComposition(result);
  11. lottieAnimationView.playAnimation();
  12. }
  13. });

动画进度监听

  1. lottieAnimationView.addAnimatorUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  2. @Override
  3. public void onAnimationUpdate(ValueAnimator valueAnimator) {
  4. if (valueAnimator.getAnimatedFraction() == 0 ){
  5. //动画开始
  6. }else if (valueAnimator.getAnimatedFraction() == 1f){
  7. //动画结束} }
  8. }
  9. );

也可以使用下边监听:

  1. lottieAnimationView.addAnimatorListener(new Animator.AnimatorListener() {
  2. @Override
  3. public void onAnimationStart(Animator animator) {
  4. //动画开始
  5. }
  6. @Override
  7. public void onAnimationEnd(Animator animator) {
  8. //动画结束
  9. }
  10. @Override
  11. public void onAnimationCancel(Animator animator) {
  12. //动画取消
  13. }
  14. @Override
  15. public void onAnimationRepeat(Animator animator) {
  16. //动画重复
  17. }
  18. });

自动播放

lottie_autoPlay="true"

循环播放

app:lottie_loop="true"

或者

lottieAnimationView.loop(true);

播放

lottieAnimationView.playAnimation();

暂停播放

lottieAnimationView.pauseAnimation();

取消播放

lottieAnimationView.cancelAnimation();

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/729845
推荐阅读
相关标签
  

闽ICP备14008679号