前言
此篇博客会举例几个自定义的Interpolator,因为Interpolator的自定义实现其实很简单(就是继承BaseInterpolator类后重写getInterpolation),所以就不介绍Interpolator的代码. 这里只讲解会有实用意义的自定义Interpolator例子
自定义Interpolator跳帧来实现逐帧动画的效果
一般情况下,动画都是顺滑流畅的. 但是有些情况下并不希望动画流畅运行. 比如一个圆形的加载动画图标. 参考这篇博客的帧动画实现:https://www.cnblogs.com/guanxinjing/p/13447854.html . 如果你点击了这个博客,看到博客里的动画就会明白如果用一张图片以旋转动画的实现是无法达这种效果的. 并且博客是用帧动画实现的.缺点很明显需要大量的图片来组成每一帧的动画,就算是使用了矢量图取巧把每一个矢量图属性都移动到一个xml, 这依然不是最小的空间是实现.
所以,这里就主要实现自定义Interpolator用一个图片的旋转动画,以跳帧(或者说抽帧,抽帧概念在电影比较多)的形式实现加载动画的逐帧效果.
当然,这种实现方式有一个缺点,那就是图片居然会抖. 我很不明白为什么会抖, 如果有大神明白请留言请教
效果图:
自定义插值器代码:
import android.os.Build; import android.view.animation.BaseInterpolator; import androidx.annotation.RequiresApi; @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1) public class FrameSkipInterpolator extends BaseInterpolator { private int mFrameSkipCount = 0; private int mInterval; private float mOfferInput = -1; /** * @param interval 需要跳过的帧数 */ public FrameSkipInterpolator(int interval){ mInterval = interval; } @Override public float getInterpolation(float input) { if (mOfferInput == -1){ mOfferInput = input; } if (mFrameSkipCount <= mInterval){ mFrameSkipCount++; return mOfferInput; } mFrameSkipCount = 0; mOfferInput = input; return mOfferInput; } }
使用它:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { loadingIcon.post { val objectAnimator: ObjectAnimator = ObjectAnimator.ofFloat(loadingIcon, "rotation", 360f, 0f) /** * 需要注意下面的持续时间与需要跳过多少帧数才能达到没有旋转效果的跳帧.是有要求的 * 其实很简单,你只需注意以下几点就能理解 * 1.你的图片有多少格子,也就是你动画旋转一圈期望执行多少帧数.比如上面加载图片就8个圆点,而我期望它选择一圈就8帧动画 * 2.动画的持续时间就是 帧数*100,所以我这里是800 , 如果你需要增加动画持续时间你需要按倍数增加 比如 1600 , 2400, 3200 等等 * 3.需要抽的帧数是, 帧数除以2, 所以我这边是4, 同理如果你增加了持续时间,你依然要按照倍数增加抽帧数量, 比如 8, 12, 16 等等 */ objectAnimator.duration = 800 objectAnimator.repeatCount = ValueAnimator.INFINITE objectAnimator.interpolator = FrameSkipInterpolator(4) objectAnimator.start() } }
End