Lottie 入门与实践

作者: Myy_Fish | 来源:发表于2017-08-31 16:43 被阅读1542次

    Lottie库Airbnb出的是一个能够帮助Android,iOS解析AE导出的包含动画信息的json文件。AE实现这个是通过Bodymovin这个插件,但是这事应该是设计师去关心的就不是开发人员去关注的了。

    美工需要做的可以参考Lottie- 让Android动画实现更简单

    [TOC]

    引入库

    dependencies {
        ...
        compile 'com.airbnb.android:lottie:2.2.0'
        ...
    }
    

    使用LottieAnimationView

    可以直接在xml中声明

    <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" 
    />
    
    • app:lottie_fileName="hello-world.json"指定了显示的动画文件,该文件放在assert文件夹下,如图:

      若要在assets的子文件夹下,例如Walthrough下的例如Walthrough.json则为:Walkthrough/Walkthrough.json
    • app:lottie_loop="true"设置是否循环播放
    • app:lottie_autoPlay="true"设置是否自动启动播放

    读取Json

    获得加载json动画文件有很多种方式:



    (1)最简单的就是之前放在asserts文件夹下,直接读取就好
    (2)还能通过网络获取Json后加载,因为找不到网络json动画资源没有测试,贴一下官方文档的代码:

    //获取json数据并实例化JsonObject
     JSONObject json = new JSONObject(response.body().string());
     Cancellable compositionCancellable = LottieComposition.Factory.fromJson(getResources(), json, (composition) -> {
         animationView.setComposition(composition);
         animationView.playAnimation();
     });
     // 通过cancel来停止对于composition的异步加载
     //compositionCancellable.cancel();
    

    动态添加

    LottieAnimationView animationView = (LottieAnimationView) findViewById(R.id.animation_view);
    animationView.setAnimation("hello-world.json");
    animationView.loop(true);
    animationView.playAnimation();
    

    具体的方法含义参考xml中声明的解释就好。

    常用方法

    • animationView.isAnimating();动画是否在播放
    • animationView.playAnimation();播放动画
    • animationView.pauseAnimation();暂停动画
    • animationView.cancelAnimation();取消动画
    • animationView.setProgress(progress); 设置进度,progress范围0~1
    • animationView.setMinAndMaxProgress(min,max); 设置播放范围,0~1,测试目前有bug,设置播放时间后再恢复播放,进度会跳过一段时间

    管理动画

    绘制监听器

    //每次动画绘制会调用
    animationView.addAnimatorUpdateListener((animation) -> {
        // 可以用来获取播放进度并同步进度条
        float progress = (Float) animation.getAnimatedValue()*100f;
        seekbar.setProgress(((int) progress));
    });
    

    自定义播放速度与区间

    //一秒内值由0变化为1,可以通过float值管理动画播放区间,设置duration控制播放速度
    ValueAnimator animator =ValueAnimator.ofFloat(0f, 1f)
        .setDuration(1000);//1s
    animator.addUpdateListener(animation -> {
        //通过由0->1的变化模拟动画播放
        animationView.setProgress(animation.getAnimatedValue());
    });
    //最终使用ValueAnimator管理动画播放
    animator.start();
    

    实践与应用

    基本动画播放与进度管理


    这个实现没什么难点,就是通过seekbar监听管理进度:

            sbBaseAnimation.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                    animationView.setProgress(progress/100f);
                }
    
                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {
                    animationView.pauseAnimation();
                    btnPlayAnim.setText("播放动画");
                }
    
                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {
                }
            });
    

    实现图标切换动画


    原理也很简单,本质上是这个图标是一个动画,list->back是从前往后播放,而back->list则是从后往前倒着播放。因为这个json动画过长,所以只截取其中一段就达到了效果,这个应用感觉对业务还是比较有用的。

        private static final int TOTAL_DURATION = 2000;
        private static final float START_PROGRESS_PART = 0.1f;
        private static final float END_PROGRESS_PART = 0.3f;
        
     //用于记录当前按钮状态
        boolean isBackState = false;
        
        @OnClick(R.id.anim_button)
        public void onViewClicked() {
            if(animatorComplete!=null&&animatorComplete.isRunning()){
                animatorComplete.cancel();
                animatorComplete = null;
            }
            //以下的参数是为了实现在动画播放到一半又需要切换时,能够直接往回播放的效果
            float progress = animButton.getProgress();
            //这次动画播放需要的时长,因为从中间挽回播时间也会变短所以要实时计算
            int nowDuration = 0;
            //这次播放起点与终点的差值
            float nowGap;
            //动画从头到尾播放的起终点差值
            float totalGap = END_PROGRESS_PART - START_PROGRESS_PART;
            if (isBackState) {
                //back->list
                nowGap = progress - START_PROGRESS_PART;
                nowDuration = (int) ((nowGap* TOTAL_DURATION)/totalGap);
                animatorComplete = ValueAnimator.ofFloat(progress, START_PROGRESS_PART)
                        .setDuration(nowDuration);
            } else {
                //list->back
                nowGap = END_PROGRESS_PART - progress;
                nowDuration = (int) ((nowGap* TOTAL_DURATION)/totalGap);
                animatorComplete = ValueAnimator.ofFloat(progress, END_PROGRESS_PART)
                        .setDuration(nowDuration);
            }
            animatorComplete.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    animButton.setProgress((Float) animation.getAnimatedValue());
                    tvProgress.setText("animatorComplete"+animation.getAnimatedValue()+"");
                }
            });
            isBackState = !isBackState;
            animatorComplete.start();
        }
    

    动画中自定义字体与动态文字

    代码实现很简单,就是原理有点弄不清楚:

    TextDelegate textDelegate = new TextDelegate(animFont);
    animationView.setTextDelegate(textDelegate);
    //这里input写为NAME(原文本)才能更改成其他文字
    textDelegate.setText("NAME","动态更改的文本");
    

    其中“NAME”这个文本是在json动画文本中指定的,动态更改需要在textDelegate.setText()中将原文本设置为在Json文件中指定的文本才能实现动态更改。
    而文本的字体是在也是在json中指定的,使用时也需要在asserts/font/文件夹下放入相应的.tts字体文件才能保证动画的正常运行。
    这一类可以实现更改动画中的字体和文本,代码参考了官方demo,但是官方文档目前没有对使用到的类进行具体说明,所以具体原理不好弄清楚,之前关于“NAME”与字体文件的相关说明也是我查看json文件后猜测得出的结论,不一定正确,仅供参考。

    引导动画

    展示效果是通过结合了sliding-intro-screen简单的实现了引导页面,然后通过监听引导页面的操作,同步管理动画的进度就实现了。具体Lottie官方的Demo中逻辑也是自己写的,没有封装。也就是说如果我们要实现这种效果的话,还是需要自己进行逻辑处理的Lottie并没有现成的包。

    打字动画


    打字动画官方是自定义了FrameLayout,代码太多所以没细看,猜测本质上也是一个个的动画view,只不过使用了有利于重用的LottieComposition

    参考文献

    lottie官方文档
    Lottie- 让Android动画实现更简单

    相关文章

      网友评论

        本文标题:Lottie 入门与实践

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