Android动画机制(2)

令你的Android APP 更优美

Posted by wushiqian on September 4, 2019

续上一篇Android动画机制

触摸反馈动画(Ripple Effect)

​ 所谓触摸反馈动画就是一种点击效果,作用在可点击的 View 上时,当有点击事件时会有涟漪般的反馈效果,使用在 按钮 上是再好不过了。 Ripple 波纹效果有两种:

//有边界
?android:attr/selectableItemBackground
//无边界 (要求API21以上)
?android:attr/selectableItemBackgroundBorderless

揭露动画(Reveal Effect)

​ 揭露动画在系统中很常见,就是类似波纹的效果, 从某一个点向四周展开或者从四周向某一点聚合起来。

​ 可以用在 Activity 里面的 View 动画效果,用来揭露某个隐藏 View 的显示;也可以使用在 Activity 跳转过渡动画中。

转场动画 & 共享元素(Activity 切换动画)

​ 转场动画听名字就知道它的使用场景了,转场、转场自然是用在场景转换的时候:

  • 转场效果我们一般用在 Activity 切换时的动画效果上;
  • 共享元素一般我们使用在转换的前后两个页面有共同元素时;
  • 同时也可以在 Activity 布局发生场景变化时,让其中的 View 产生相应的过渡动画。

视图状态动画(Animate View State Changes)

​ 所谓视图状态动画,就是 View 在状态改变时执行的动画效果。和之前我们通过 selector 选择器给 Button 设置不同状态下的背景效果是一样一样的。 ​ 当然,它的使用场景也是特定的:当 View 的状态改变时,希望此时显示的效果和静态效果有所区分,即显示效果也做出相应的改变,比如 Z 轴抬高,大小改变、或其他动画效果等。

约束布局实现的关键帧动画(ConstraintSet 动画)

​ 这是通过 ConstraintLayout 实现的一种关键帧动画。

​ 关键帧动画:(来自百度百科) 任何动画要表现运动或变化,至少前后要给出两个不同的关键状态,而中间状态的变化和衔接电脑可以自动完成,在 Flash 中,表示关键状态的帧动画叫做关键帧动画 ​ 所谓关键帧动画,就是给需要动画效果的属性,准备一组与时间相关的值,这些值都是在动画序列中比较关键的帧中提取出来的,而其他时间帧中的值,可以用这些关键值,采用特定的插值方法计算得到,从而达到比较流畅的动画效果。

Lottie

Lottie 是一个可应用于Andriod和iOS的动画库,它通过bodymovin插件来解析Adobe After Effects 动画并导出为json文件,通过手机端原生的方式或者通过React Native的方式渲染出矢量动画

Lottie官网

使用方式

  1. 导入Lottie库

  2. 导入动画文件

  3. 使用姿势 1)静态方式 Lottie库提供了一个LottieAnimationView控件,它本质是一个ImageView,可直接在布局文件中声明:

       <com.airbnb.lottie.LottieAnimationView
       			android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:lottie_fileName="anim.json"
            app:lottie_loop="true"
            app:lottie_autoPlay="true"/>
    

这里列举了有几个lottie的基本属性

  • lottie_fileName 调用的Json文件名

  • lottie_loop 是否开启循环动画

  • lottie_autoPlay 是否开启自动播放,当然lottie还有很多其他的属性,例如:

  • lottie_repeatCount 动画重复次数

  • lottie_repeatMode 动画重复模式

  • lottie_scale 放大倍数

    2)动态方式 Lottie也支持在代码中动态调用接口:

 LottieAnimationView lottieAnimationView = findViewById(R.id.anim_view);
 lottieAnimationView.setAnimation("anim.json");
 lottieAnimationView.loop(true);
 lottieAnimationView.playAnimation();

3)监听动画进度 Lottie同样提供了监听动画的接口,而且还是我们熟悉的ValueAnimator

lottieAnimationView.addAnimatorUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                // 判断动画加载结束
                Log.d("Lottie", "" + valueAnimator.getAnimatedFraction());
            }
});

4)加载动画优化

Lottie的性能比属性动画略逊一筹,不过支持开启硬件加速:lottieAnimationView.useHardwareAcceleration(true);

Lottie支持对动画的缓存,会在动画加载完成后将其缓存为强缓存和弱缓存

lottieAnimationView.setAnimation("anim.json", LottieAnimationView.CacheStrategy.Strong);    //强缓存
lottieAnimationView.setAnimation("anim.json", LottieAnimationView.CacheStrategy.Weak);      //弱缓存

其内部是维护了两个HashMap:

private static final Map<String, LottieComposition> STRONG_REF_CACHE = new HashMap<>();
private static final Map<String, WeakReference<LottieComposition>> WEAK_REF_CACHE =
      new HashMap<>();
public void setAnimation(final String animationName, final CacheStrategy cacheStrategy) {
    //......
    if (cacheStrategy == CacheStrategy.Strong) {
      STRONG_REF_CACHE.put(animationName, composition);
    } else if (cacheStrategy == CacheStrategy.Weak) {
      WEAK_REF_CACHE.put(animationName, new WeakReference<>(composition));
    }
    //.....
}

参考: Lottie for Android:一个解放开发者双手的动画神器 Lottie : 让动画如此简单