小动画之“加载”

用属性动画ValueAnimator实现加载小动画

  • 1. 属性动画什么?
  • 2. 对图片实现跳跃加载动画
    • 2.1 需求
    • 2.2 实现思路
    • 2.3 图片动画的实现
    • 2.4 注意
  • 3. 对文字实现加载动画
    • 3.1 需求
    • 3.2 代码
    • 3.3 问题
  • 4. 取消动画
  • 5. 吐槽

小动画之“加载”_第1张图片

1. 属性动画什么?

属性动画能够只针对控件的某一个属性来做动画,它能单独改变控件某一个属性的值,比如颜色。
属性动画能实现补间动画无法实现的功能。
视图动画仅能对指定的控件做动画, 而属性动画是通过改变控件的某一属性值来做动画的。

2. 对图片实现跳跃加载动画

2.1 需求

  1. 动画执行动画,上升下降;
  2. 一次循环结束更换图片信息;

2.2 实现思路

  1. 创建一个类继承自ImageView 类,这样方便地更改它的源文件内容。
  2. 要想实现上下移动的效果,可利用 ValueAnimator 实时产生 0~ 100 的数值,通过设置监听让当前图片的位置实时向上移动。

2.3 图片动画的实现

源码都在这里了。

public class LoadingImageView extends androidx.appcompat.widget.AppCompatImageView {
	//用于实时
    private int mTop;
    private ValueAnimator animator;

    private int curImgIndex = 0;
    private int mImageCount = 7;

    public LoadingImageView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        animator = ValueAnimator.ofInt(0, 100, 0);
        animator.setDuration(1000);
        animator.setRepeatMode(ValueAnimator.RESTART);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setInterpolator(new AccelerateDecelerateInterpolator());

        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Integer dy = (Integer) animation.getAnimatedValue();
                setTop(mTop - dy);
            }
        });

        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                setImageDrawable(getResources().getDrawable(R.drawable.channel2));
            }

            @Override
            public void onAnimationEnd(Animator animation) {

            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                //每重复一次就更换一次图片 放在 这个方法中写。
                curImgIndex++;
                int i = curImgIndex % mImageCount + 1 ;
                //通过文件名拿到对应的资源ID;当循环到第7张,7 % 7 = 0;没有匹配的图片。故统一向前加 1
                int id = getResources().getIdentifier("channel" + i, "drawable", "com.example.customview");
                Log.i("TAG", "image id is : " + id);
                Drawable drawable = getResources().getDrawable(id);
                setImageDrawable(drawable);
            }
        });
        animator.start();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        mTop = top;
    }
}

2.4 注意

  1. 这里 通过文件名拿到对应的资源ID,动态加载图片;

  2. 当循环到第 7 张图片,7 % 7 = 0;没有匹配的图片。故统一向前加 1;

  3. 这里的参数是:getIdentifier(filename,filetype,packagename);

    int id = getResources().getIdentifier("channel" + i, "drawable", "com.example.customview");
    Drawable drawable = getResources().getDrawable(id);
    setImageDrawable(drawable);
    

3. 对文字实现加载动画

3.1 需求

  1. 实现如图所示,"加载中…" 一个一个蹦出来的动画效果;
  2. 文字随时间改变背景颜色,这里涉及到 ArgbEvaluator;Evaluator 是将动画进度(小数类型)转换实际进度的类;

3.2 代码

private void loadingTv() {
	//这里并没有实时监听他的动作。
    mValueAnimator = ValueAnimator.ofInt(0, 3);
    mValueAnimator.setDuration(1000);
    mValueAnimator.setRepeatCount(ValueAnimator.INFINITE);
    mValueAnimator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
        }
        @Override
        public void onAnimationEnd(Animator animation) {
        }
        @Override
        public void onAnimationCancel(Animator animation) {
        }
        @Override
        public void onAnimationRepeat(Animator animation) {
            times++;
            switch (times % 4) {
                case 2:
                    tv_loading.setText("加");
                    break;
                case 3:
                    tv_loading.append("载");
                    break;
                case 0:
                    tv_loading.append("中");
                    break;
                case 1:
                    tv_loading.append("…");
                    break;
                default:
                    break;
            }
        }
    });
    mValueAnimator.start();
    //ArgbEvaluator 实现颜色值过渡转换的。
    mColorValueAnimator = ValueAnimator.ofInt(0xffffff00,0xff0000ff);
	mColorValueAnimator.setDuration(3000);
	mColorValueAnimator.setEvaluator(new ArgbEvaluator());
	mColorValueAnimator.setRepeatCount(ValueAnimator.INFINITE);
	mColorValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
	    @Override
	    public void onAnimationUpdate(ValueAnimator animation) {
	        Integer curValue = (Integer) mColorValueAnimator.getAnimatedValue();
	        tv_loading.setTextColor(curValue);
	    }
	});
	mColorValueAnimator.start();
}

3.3 问题

  1. 更新文字个数绝不是最好的办法,因为反反复复的刷新 UI 必然会造成内存浪费,更好的办法会继续更新。
  2. 更改文字颜色:须使用Va lueAnimator.oflnt()函数来定义颜色的取值范围,并且颜色必须包括A 、R 、G 、B4 个值。

4. 取消动画

切记:对于执行了无限重复的动画,在 activity 销毁之前一定要执行 cancel。

if (rotateAnimation != null) {
    rotateAnimation.cancel();
}
mValueAnimator.cancel();

5. 吐槽

  1. 做动画遇到的问题:重复更新 UI 或者图片,都是在 onAnimationRepeat() 中执行的;
  2. 做动画的过程中遇到的问题,Java 半小时,动画八小时……
  3. 如何将手机录屏的竖屏视频截取一段横屏?
    1. 打开 PR 导入素材,并拖至时间轴,如果你不需要声音,可以点击时间轴中,下面一条右键选中 “取消链接” ,随后即可 delete 删除下边的音频;
    2. 此时,视频是竖直的,点击顶部,序列 - 序列设置 - 帧大小;将横竖参数进行修改,
      小动画之“加载”_第2张图片
    3. 截取视频;双击右上角视频区,选择效果,打开右边栏 - 视频效果 - 变换 - 剪裁 - 在左边栏进行尺寸剪裁以及放大操作。
    4. 如果视频不是很~讲究,导出时不必搞得像素很高,那会导致文件很大。
    5. 视频300KB,导出的GIF6MB?
      Pr导出GIF时,修改导出设置,
      1. 格式:动画gif,预设:改自du定义zhi!
      2. 然后仅 导出视频,不要勾选导出音频;
      3. 在基本设置栏里,把宽度高度,改为宽3201804. 帧速率改为2(每秒2帧),帧速率越低,图片越小,不过会造成一顿一顿的,视情况调整。
      

你可能感兴趣的:(Android学习总结)