Android自定义View-视图动画

278 阅读2分钟

1、补间动画

demo地址:

github.com/chaozhouzha…

1.1、缩放

xml实现

/**
 * <scale xmlns:android="http://schemas.android.com/apk/res/android"
 * android:duration="1000"
 * android:fillAfter="true"
 * android:fillBefore="false"
 * android:fillEnabled="false"
 * android:fromXScale="1.5"
 * android:fromYScale="1.5"
 * android:interpolator="@android:anim/accelerate_interpolator"
 * android:pivotX="50%"
 * android:pivotY="50%"
 * android:repeatCount="infinite"
 * android:repeatMode="reverse"
 * android:toXScale="0.5"
 * android:toYScale="0.5">
 * </scale>
 * 
 * 完成一次动画的持续时间,单位毫秒
 * 动画结束后,停留在结束时的状态
 * 动画结束后,回到开始前的状态
 * 动画结束后,回到开始前的状态
 * 动画开始时空间在X轴相对自身的缩放比例
 * 动画开始时空间在Y轴相对自身的缩放比例
 * 插值器:指定动画效果
 * 缩放起始点X轴坐标:以当前控件的左上角为原点加上:数值、百分数(自身宽度的百分数)、百分数p(父控件宽度的百分数)
 * 缩放起始点Y轴坐标:以当前控件的左上角为原点加上:数值、百分数(自身高度的百分数)、百分数p(父控件高度的百分数)
 * 重复次数:infinite为无限循环
 * 重复模式:reverse为倒序回放;restart为重放,且必须与repeatCount一起使用
 * 动画结束时空间在X轴相对自身的缩放比例
 * 动画结束时空间在Y轴相对自身的缩放比例
 *
 */
private void xmlAnimation() {
    Animation animation = AnimationUtils.loadAnimation(this, R.anim.scale_test);
    mIvTest.startAnimation(animation);
}

代码实现

private void codeAnimation() {
    ScaleAnimation scaleAnimation = new ScaleAnimation(1.5f,0.5f,1.5f,0.5f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    scaleAnimation.setDuration(1000);
    scaleAnimation.setFillAfter(true);
    scaleAnimation.setFillBefore(false);
    scaleAnimation.setFillEnabled(false);
    scaleAnimation.setRepeatCount(Animation.INFINITE);
    scaleAnimation.setRepeatMode(Animation.REVERSE);
    scaleAnimation.setInterpolator(new AccelerateInterpolator());
    mIvTest.startAnimation(scaleAnimation);
}

1.2、不透明度

xml实现

/**
 * <alpha xmlns:android="http://schemas.android.com/apk/res/android"
 * android:fromAlpha="1.0"
 * android:duration="1000"
 * android:repeatMode="reverse"
 * android:repeatCount="infinite"
 * android:toAlpha="0.1">
 * </alpha>
 * 动画开始时的透明度:0-1
 * 动画结束时的透明度:0-1
 *
 */
 private void xmlAnimation() {
    Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha_test);
    mIvTest.startAnimation(animation);
}

代码实现

private void codeAnimation() {
    AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f,0.1f);
    alphaAnimation.setDuration(1000);
    alphaAnimation.setRepeatCount(Animation.INFINITE);
    alphaAnimation.setRepeatMode(Animation.REVERSE);
    mIvTest.startAnimation(alphaAnimation);
}

1.3、位移

xml实现

/**
 * <translate xmlns:android="http://schemas.android.com/apk/res/android"
 * android:fromXDelta="10%"
 * android:fromYDelta="10%"
 * android:toXDelta="100%"
 * android:toYDelta="100%"
 * android:duration="1000"
 * android:repeatCount="infinite"
 * android:repeatMode="reverse"
 * >
 * </translate>
 * 起始点X轴坐标
 * 起始点Y轴坐标
 * 结束点X轴坐标
 * 结束点Y轴坐标
 *
 */
private void xmlAnimation() {
    Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate_test);
    mIvTest.startAnimation(animation);
}

代码实现

private void codeAnimation() {
    TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.1f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0.1f, Animation.RELATIVE_TO_SELF, 1.0f);
    translateAnimation.setDuration(1000);
    translateAnimation.setRepeatCount(Animation.INFINITE);
    translateAnimation.setRepeatMode(Animation.REVERSE);
    mIvTest.startAnimation(translateAnimation);
}

1.4、旋转

xml实现

/**
 * <rotate xmlns:android="http://schemas.android.com/apk/res/android"
 * android:fromDegrees="90"
 * android:pivotY="50%"
 * android:pivotX="50%"
 * android:drawable="@color/colorAccent"
 * android:visible="true"
 * android:duration="1000"
 * android:repeatCount="infinite"
 * android:repeatMode="reverse"
 * android:toDegrees="-270"
 * >
 * </rotate>
 * 动画开始旋转时的角度位置:正数顺时针,负数逆时针
 * 动画结束旋转时的角度位置:正数顺时针,负数逆时针
 *
 */
private void xmlAnimation() {
    Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate_test);
    mIvTest.startAnimation(animation);
}

代码实现

private void codeAnimation(){
    RotateAnimation rotateAnimation = new RotateAnimation(90,-270,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    rotateAnimation.setDuration(1000);
    rotateAnimation.setRepeatCount(Animation.INFINITE);
    rotateAnimation.setRepeatMode(Animation.REVERSE);
    mIvTest.startAnimation(rotateAnimation);
}

1.5、集合

xml实现

/**
 * <set xmlns:android="http://schemas.android.com/apk/res/android"
 * android:duration="1000"
 * android:fillAfter="true"
 * android:fillBefore="false"
 * android:fillEnabled="false">
 * <scale
 * android:fromXScale="1.5"
 * android:fromYScale="1.5"
 * android:interpolator="@android:anim/accelerate_interpolator"
 * android:pivotX="50%"
 * android:pivotY="50%"
 * android:repeatCount="infinite"
 * android:repeatMode="reverse"
 * android:toXScale="0.5"
 * android:toYScale="0.5">
 * </scale>
 * <alpha
 * android:fromAlpha="1.0"
 * android:repeatMode="reverse"
 * android:repeatCount="infinite"
 * android:toAlpha="0.1">
 * </alpha>
 * <rotate
 * android:fromDegrees="90"
 * android:pivotY="50%"
 * android:pivotX="50%"
 * android:drawable="@color/colorAccent"
 * android:visible="true"
 * android:repeatCount="infinite"
 * android:repeatMode="reverse"
 * android:toDegrees="-270">
 * </rotate>
 * <translate
 * android:fromXDelta="10%"
 * android:fromYDelta="10%"
 * android:toXDelta="100%"
 * android:toYDelta="100%"
 * android:repeatCount="infinite"
 * android:repeatMode="reverse">
 * </translate>
 * </set>
 * set中:repeatCount标签无效
 *
 */
private void xmlAnimation() {
    Animation animation = AnimationUtils.loadAnimation(this, R.anim.set_test);
    mIvTest.startAnimation(animation);
}

代码实现

private void codeSetAnimation() {
    animationSet = new AnimationSet(true);
    animationSet.addAnimation(codeScaleAnimation());
    animationSet.addAnimation(codeAlphaAnimation());
    animationSet.addAnimation(codeRotateAnimation());
    animationSet.addAnimation(codeTranslateAnimation());
    animationSet.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {//动画开始
            Toast.makeText(SetAnimationActivity.this, "动画开始", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onAnimationEnd(Animation animation) {//动画结束
            Toast.makeText(SetAnimationActivity.this, "动画结束", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onAnimationRepeat(Animation animation) {//动画重复
            Toast.makeText(SetAnimationActivity.this, "重复动画", Toast.LENGTH_SHORT).show();

        }
    });
    mIvTest.startAnimation(animationSet);
}

2、逐帧动画

demo地址:

github.com/chaozhouzha…

xml实现

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item
        android:drawable="@mipmap/loading_01"
        android:duration="50"></item>
    <item
        android:drawable="@mipmap/loading_02"
        android:duration="50"></item>
    <item
        android:drawable="@mipmap/loading_03"
        android:duration="50"></item>
    <item
        android:drawable="@mipmap/loading_04"
        android:duration="50"></item>
    <item
        android:drawable="@mipmap/loading_05"
        android:duration="50"></item>

    <item
        android:drawable="@mipmap/loading_06"
        android:duration="50"></item>
    <item
        android:drawable="@mipmap/loading_07"
        android:duration="50"></item>
    <item
        android:drawable="@mipmap/loading_08"
        android:duration="50"></item>
    <item
        android:drawable="@mipmap/loading_09"
        android:duration="50"></item>
    <item
        android:drawable="@mipmap/loading_010"
        android:duration="50"></item>

</animation-list>
private void xmlAnimation() {
    AnimationDrawable animationDrawable = (AnimationDrawable) mIvLoading.getDrawable();
    animationDrawable.start();
}

代码实现

/**
 * oneshot 表示是否只执行一次
 */
public void codeAnimation() {
    int num = 10;
    AnimationDrawable animationDrawable = new AnimationDrawable();
    for (int i = 1; i <= num; i++) {
        int id = getResources().getIdentifier("loading_0" + i, "mipmap", getPackageName());
        Drawable drawable = getResources().getDrawable(id);
        animationDrawable.addFrame(drawable, 50);
    }
    animationDrawable.setOneShot(false);
    mIvLoadingCode.setBackgroundDrawable(animationDrawable);
    animationDrawable.start();
}

3、插值器

demo地址:

github.com/chaozhouzha…

TranslateAnimation translateAnimation = codeAnimation();
switch (v.getId()) {
    case R.id.btn_accelerate_decelerate:
        translateAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
        break;
    case R.id.btn_accelerate:
        translateAnimation.setInterpolator(new AccelerateInterpolator());
        break;
    case R.id.btn_decelerate:
        translateAnimation.setInterpolator(new DecelerateInterpolator());
        break;
    case R.id.btn_linear:
        translateAnimation.setInterpolator(new LinearInterpolator());
        break;
    case R.id.btn_bounce:
        translateAnimation.setInterpolator(new BounceInterpolator());
        break;
    case R.id.btn_overshoot:
        translateAnimation.setInterpolator(new OvershootInterpolator());
        break;
    case R.id.btn_anticipate:
        translateAnimation.setInterpolator(new AnticipateInterpolator());
        break;
    case R.id.btn_anticipate_overshoot:
        translateAnimation.setInterpolator(new AnticipateOvershootInterpolator());
        break;
    case R.id.btn_cycle:
        translateAnimation.setInterpolator(new CycleInterpolator(1));
        break;
    default:
        break;
}
mIvTest.startAnimation(translateAnimation);

欢迎关注Android技术堆栈公众号: