Lottie for Android实战使用总结

作者: 燊在锦官城 | 来源:发表于2018-09-06 15:05 被阅读3次
    Introduction.gif

    1. 使用准备

    Lottie支持多平台,使用同一个JSON动画文件,可在不同平台实现相同的效果。Android 通过Airbnb的开源项目lottie-android实现,最低支持 API 16;

    在项目的 build.gradle 文件添加依赖

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

    最新的版本号可以到官网或者github查询,lottie仅支持api16及以上。

    2. 加载方式

    • src/main/assets
      文件分级.png
            lottieAnimationView = findViewById(R.id.animation_view);
            lottieAnimationView.setImageAssetsFolder("images");
            lottieAnimationView.setAnimation("data.json");
            lottieAnimationView.loop(true);
            lottieAnimationView.playAnimation();
    
    <com.airbnb.lottie.LottieAnimationView
                android:id="@+id/animation_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:lottie_fileName="hello-world.json"
                app:lottie_loop="true"
                app:lottie_autoPlay="true" />
    
    • Json String

    加载服务器上的.json文件,若有图片可以设置本地代理文件夹或者将图片资源放入 JSON。

    private void loadUrl(String url) {
            Request request = new Request.Builder().url(url).build();
            OkHttpClient client = new OkHttpClient();
            client.newCall(request).enqueue(new Callback() {
                @Override public void onFailure(Call call, IOException e) {}
                @Override public void onResponse(Call call, Response response) throws IOException {
                    try {
                        JSONObject json = new JSONObject(response.body().string());
                        LottieComposition.Factory
                                .fromJson(getResources(), json, new OnCompositionLoadedListener() {
                                    @Override
                                    public void onCompositionLoaded(LottieComposition composition) {
                                        lottieAnimationView.setComposition(composition);
                                        lottieAnimationView.playAnimation();
                                    }
                                });
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
    • Url 服务器上的压缩包(包含images和json文件)
        // 资源zip
        public final static File LOTTIE_FILES = new File(Environment.getExternalStorageDirectory()+"/ctclient/lottie/lottie.zip");
        // 动效图片资源
        public final static File IMAGES_FILES = new File(Environment.getExternalStorageDirectory()+"/ctclient/lottie/images");
        // data.json路径
        public final static File JSON_FILE = new File(Environment.getExternalStorageDirectory()+"/ctclient/lottie/data.json");
        
        FileInputStream fis = null;
        if (JSON_FILE.exists()) {
            try {
                fis = new FileInputStream(JSON_FILE);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        if (fis == null || !IMAGES_FILES.exists()) {
            Log.i("huangssh", "动画资源不存在");
            return;
        }
        final String absolutePath = IMAGES_FILES.getAbsolutePath();
        // 开启硬件加速
        lottieSolar.useHardwareAcceleration(true);
        // 设置动画文件夹代理类
        lottieSolar.setImageAssetDelegate(new ImageAssetDelegate() {
            @Override
            public Bitmap fetchBitmap(LottieImageAsset asset) {
                BitmapFactory.Options opts = new BitmapFactory.Options();
                opts.inScaled = true;
                opts.inDensity = UtilPhoneParam.densityDpi;
                Bitmap bitmap = null;
                try {
                    bitmap = BitmapFactory.decodeFile(absolutePath + File.separator + asset.getFileName(), opts);
                }catch (Exception e){
                    e.printStackTrace();
                }
                return bitmap;
            }
        });
        
        // 设置动画
        LottieComposition.Factory.fromInputStream(fis, new OnCompositionLoadedListener() {
            @Override
            public void onCompositionLoaded(@Nullable LottieComposition composition) {
                lottieSolar.setComposition(composition);
                lottieSolar.playAnimation();
            }
        });
    
    • 加载SDCard字体
    animationView.setFontAssetDelegate(new FontAssetDelegate(){
        public Typeface fetchFont(String fontFamily) {
            Typeface customFont = Typeface.createFromFile(FONT_PATH + fontFamily);
            return customFont;
        }
    });
    
    • 监听动画进度 [0,1]
        lottieSolar.addAnimatorUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                // 判断动画加载结束
                if (valueAnimator.getAnimatedFraction() == 1f) {
                    if (dialog.isShowing() && getActivity() != null)
                        dialog.dismiss();
                }
            }
        });
    
    • 循环

    在xml中

    lottie_loop="true"
    

    代码中

    lottieAnimationView.loop(true);
    

    你也可以像ValueAnimator一样使用setRepeatMode(...)setRepeatCount(...)

    • scaleType

    只支持centerCropcenterInside

    • 播放动画的某个部分
    setMinFrame(...)
    setMaxFrame(...)
    setMinProgress(...)
    setMaxProgress(...)
    setMinAndMaxFrame(...)
    setMinAndMaxProgress(...)
    
    • 硬件加速,解决lottie卡顿问题
    lottieSolar.useHardwareAcceleration(true);
    
    • 缓存
    /*
    * Lottie内部有两个缓存map(强引用缓存,弱引用缓存),在动画文件加载完成后会根据设置的缓存策略缓存动画,方便下次使用。
    */
    animationView.setAnimation(animation, LottieAnimationView.CacheStrategy.Strong);    //强缓存
    
    animationView.setAnimation(animation, LottieAnimationView.CacheStrategy.Weak);      //弱缓存
    

    根据进度缓存,并为下次播放作准备

    animationView.setProgress(progress);        //设置当前进度
    animationView.buildDrawingCache();          //强制缓存绘制数据
    Bitmap image = animationView.getDrawingCache(); //获取当前绘制数据
    

    3. After Effects方面注意点(for设计师)

    1. 官网动画实例 www.lottiefiles.com
    2. ae文件预览
      https://www.lottiefiles.com/preview
    3. 在为Lottie构建时,您始终必须记住,这些JSON文件需要尽可能小巧令移动产品尽可能小。 例如,尽可能使用parenting。 在类似的图层上复制相同的关键帧会增加额外的代码。 只有在必要时才使用路径关键帧动画。 由于它为每个关键帧上的每个顶点添加数据,因此占用的空间最多。 诸如Autotrace之类的技术,或者每帧都为您提供关键帧的摇摆器,可能会使您的JSON文件非常大,并可能会对性能产生负面影响。 必须与组合物的设置方式保持平衡,以使事物尽可能高效。
    4. 将任何Adobe Illustrator,EPS,SVG或PDF资源转换为After Effects中的图层,否则它们将无法在您的Lottie动画中使用。
    5. Lottie尚不支持效果菜单中的表达式或任何效果。
    6. 使用alpha遮罩会影响性能。 如果你使用的是alpha遮罩或alpha倒置遮罩,遮罩的大小会对性能产生更大的影响。 如果必须使用遮罩,请覆盖最小的区域。
    7. 混合模式(如Multiply, Screen 或 Add)尚不受支持,也不支持Luma遮罩。
    8. Lottie还不支持阴影,颜色叠加或笔触等图层效果。
    9. 导出比您想要支持的最宽屏幕更宽的动画,使开发者在Android上使用centerCrop类型或在iOS上使用aspectFill内容模式。
    10. 将图片资源放入JSON, 将图片资源整合到动画的 JSON文件中,开发人员的工作量就可以节约很多。
    • 需要先将图片转换成矢量图 SVG 格式,这个设计师一定有办法。
    • 使用 Illustrator 将 SVG 文件另存为 .ai 文件。
    • 使用 .ai 文件在 AE 中做动画处理。
    • 最后通过 Bodymovin 插件,输出动画资源。
      官方文档: artwork-to-lottie-walkthrough

    参考

    相关文章

      网友评论

        本文标题:Lottie for Android实战使用总结

        本文链接:https://www.haomeiwen.com/subject/mujxgftx.html