学习Android的View体系一定要了解甚至熟练运用动画,才能做出优秀的应用,这里强调是View/ViewGroup体系下的动画,因为又新出了Jetpack Compose体系的动画,后续会总结姊妹篇出来。
import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
/**
* Android 动画的思考?
* 1.补间动画 View Animation:(旋转、渐变透明度、尺寸缩放、位置平移、动画集合)
* 2.属性动画 Property Animation:修改控件的属性值,实现动画效果
* 3.帧动画:Drawable Animation
*/
public class AnimationUtil {
/**
* 一、帧动画 AnimationDrawable
* 按照顺序加载一系列的图片资源形成一个视觉动画,
* 动画的创建类似于传统的电影胶卷播放。
* Drawable是一种而可视化资源,比如简单的颜色、图片、Shape等,
* 同时,Drawable是一个类,但是这个类的实例可以通过XML文件的形式创建。
* XML Res:
* <animation-list>
* <item android:drawable="@drawable/ic_run1" android:duration="100"/>
* <item android:drawable="@drawable/ic_run2" android:duration="100"/>
* <item android:drawable="@drawable/ic_run3" android:duration="100"/>
* <item android:drawable="@drawable/ic_run4" android:duration="100"/>
* ...
* </animation-list>
*/
/**
* 二、补间动画的封装
* 1.位置平移 TranslateAnimation:translationX、translationY、translationZ
* 2.渐变透明度 AlphaAnimation:alpha 透明度全透明到不透明,0f~1f
* 3.旋转 RotateAnimation:rotation 旋转一圈,0f~360f
* 4.尺寸缩放 ScaleAnimation:水平缩放scaleX,垂直缩放scaleY
* 5.动画集合 AnimationSet
*
* @param view
* @param scaleSmall
* @param scallLarge
* @param shakeDegrees
* @param duration
*/
public static void startShakeByViewAnim(View view, float scaleSmall, float scallLarge,float shakeDegrees, long duration) {
if (view == null) {
return;
}
// 有小变大
Animation scaleAnim = new ScaleAnimation(scaleSmall, scallLarge, scaleSmall, scallLarge);
// 从左向右
Animation rotateAnim = new RotateAnimation(-shakeDegrees, shakeDegrees,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnim.setDuration(duration);
rotateAnim.setDuration(duration / 10);
rotateAnim.setRepeatMode(Animation.REVERSE);
rotateAnim.setRepeatCount(10);
AnimationSet smallAnimationSet = new AnimationSet(false);
smallAnimationSet.addAnimation(scaleAnim);
smallAnimationSet.addAnimation(rotateAnim);
view.startAnimation(smallAnimationSet);
}
/**
* 三、属性动画 — Keyframe
* https://developer.android.com/reference/android/animation/Keyframe
* 1.动画归根结底是一些帧的组合,一旦设定了一个动画后,Android系统会帮我们计算好中间的每一帧,
* 而Keyframe允许我们定义动画中的一些关键帧,该对象主要有fraction和value组成,
* 其中fraction代表着动画的进度,value代表着动画的值。
* 2.动画需要控制速率的变化,需要自定义插值器和估值器,
* 借助Keyframe让我们可以指定某个属性百分比时对象的属性,这样速率的变化就是动画的展示。
* @param view
* @param scaleSmall
* @param scallLarge
* @param shakeDegrees
* @param duration
*/
public static void startShakeByPropertyAnim(View view, float scaleSmall, float scallLarge, float shakeDegrees, long duration) {
if (view == null) {
return;
}
// 先变小后变大
PropertyValuesHolder scaleXValuesHolder = PropertyValuesHolder.ofKeyframe(View.SCALE_X,
Keyframe.ofFloat(0f,1.0f),
Keyframe.ofFloat(0.25f,scaleSmall),
Keyframe.ofFloat(0.5f,scallLarge),
Keyframe.ofFloat(0.75f,scallLarge),
Keyframe.ofFloat(1.0f,1.0f)
);
PropertyValuesHolder scaleYValuesHolder = PropertyValuesHolder.ofKeyframe(View.SCALE_Y,
Keyframe.ofFloat(0f,1.0f),
Keyframe.ofFloat(0.25f,scaleSmall),
Keyframe.ofFloat(0.5f,scallLarge),
Keyframe.ofFloat(0.75f,scallLarge),
Keyframe.ofFloat(1.0f,1.0f)
);
// 先往左再往右
PropertyValuesHolder rotateValuesHolder = PropertyValuesHolder.ofKeyframe(View.ROTATION,
Keyframe.ofFloat(0f,0f),
Keyframe.ofFloat(0.1f,-shakeDegrees),
Keyframe.ofFloat(0.2f,shakeDegrees),
Keyframe.ofFloat(0.3f,-shakeDegrees),
Keyframe.ofFloat(0.4f,shakeDegrees),
Keyframe.ofFloat(0.5f,-shakeDegrees),
Keyframe.ofFloat(0.6f,shakeDegrees),
Keyframe.ofFloat(0.7f,-shakeDegrees),
Keyframe.ofFloat(0.8f,shakeDegrees),
Keyframe.ofFloat(0.9f,-shakeDegrees),
Keyframe.ofFloat(1.f,0f)
);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(view, scaleXValuesHolder,
scaleYValuesHolder,rotateValuesHolder);
objectAnimator.setDuration(duration);
objectAnimator.start();
}
}