Android动画一
Android动画分为视图动画和属性动画
Android框架定义了透明度、旋转、缩放、位移几种常见动画
一、视图动画
1.1 实现原理
1、ViewGroup通过drawChild获取View的Animation(动画[ˌænɪˈmeɪʃn])的Transformation(变化、转换[ˌtrænsfəˈmeɪʃn])值
2、调用canvas.concat(transformToApply.getMatrix()),通过矩阵运算完成动画帧
3、动画没有完成会一直调用invalidate()
1.2 视图动画种类
AlphaAnimation(透明度[ˈælfə]) 透明动画
RotateAnimation 旋转动画
TranslateAnimation 位移动画
ScaleAnimation 缩放动画
AnimationSet 动画集合
视图动画不具备交互性,响应事件的位置在动画前的地方
1.3 透明度动画
AlphaAnimation aa = new AlphaAnimation(0, 1);// 从透明到不透明
aa.setDuration(1000);
v.startAnimation(aa);
1.4 旋转动画
// RotateAnimation ra = new RotateAnimation(0, 360, v.getWidth()/2, v.getHeight()/2);// 旋转开始角度结束角度,旋转中心
RotateAnimation ra = new RotateAnimation(0, 360, RotateAnimation.RELATIVE_TO_SELF, 0.5f ,
Animation.RELATIVE_TO_SELF, 0.5f);// 旋转开始角度结束角度,旋转中心
ra.setDuration(1000);
v.startAnimation(ra);
1.5 平移动画
TranslateAnimation ta = new TranslateAnimation(0, 200, 0, 300);// x起动到终点 y起点到终点 相对值
ta.setDuration(1000);
v.startAnimation(ta);
1.6 缩放动画
// ScaleAnimation sa = new ScaleAnimation(0, 2, 0, 2);// 缩放倍数 缩放中心
ScaleAnimation sa = new ScaleAnimation(0, 2, 0, 2, ScaleAnimation.RELATIVE_TO_SELF, 0.5f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f);// 以自身为中心
sa.setDuration(1000);
v.startAnimation(sa);
1.7 动画集合
AnimationSet as = new AnimationSet(true);
as.setDuration(1000);
AlphaAnimation a = new AlphaAnimation(0, 1);
a.setDuration(1000);
as.addAnimation(a);
TranslateAnimation t = new TranslateAnimation(0, 100, 0, 200);
t.setDuration(1000);
as.addAnimation(t);
v.startAnimation(as);
1.8 动画监听
// 动画监听
as.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
1.9 运行效果

二、属性动画
Animator动画师,通过这个也可以区分是否属性动画
与视图动画对应的有AnimatorSet、ObjectAnimator
ObjectAnimator只控制对象的一个属性
ObjectAnimator可以自己驱动,调用setFrameDelay(longframeDelay)设置动画帧之间的间隙时间,减少动画过程中频繁绘制,在不影响效果前提下减少cpu资源消耗
ObjectAnimator通过调用属性的get、set方法来控制一个View的属性值
2.1 ObjectAnimator使用
使用静态工厂类返回ObjectAnimator对象,参数包括对象属性名字,属性必须有get、set方法,内部通过java反射机制调用
2.2 属性动画包含的属性值
属性必须有set、get方法,否则ObjectAnimator无效
translationX translationY
rotation rotationX rotationY
scaleX scaleY
pivotX pivotY View对象的支点位置,围绕支点进行缩放、变换处理,默认就是View的中心点
x y 就是左上角坐标和translationX、translationY的累计和
alpha
2.3 没有get、set方法的解决
1、通过包装类增加get、set方法
rivate static class WrapperView{
private View mTarget;
public WrapperView(View target){
this.mTarget = target;
}
public int getWidth(){
return mTarget.getLayoutParams().width;
}
public void setWidth(int width){
mTarget.getLayoutParams().width = width;
mTarget.requestLayout();
}
}
WrapperView wrapper = new WrapperView(view);
ObjectAnimator animator1 = ObjectAnimator.ofInt(wrapper, "width", 500);
animator1.setDuration(5000).start();
2、通过ValueAnimator提供的变化值,自己实现动画效果
ObjectAnimator继承自ValueAnimator,那么就通过ValueAnimator提供的值,由调用者控制动画的实现过程
ValueAnimator本身不提供任何动画效果
ValueAnimator animator2 = ValueAnimator.ofFloat(0, 100);
animator2.setTarget(view);
animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Float value = (Float) animation.getAnimatedValue();
System.out.println(value);
}
});
animator2.setDuration(1000).start();
2.4 动画监听
监听全部事件
animator.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) {
}
});
监听部分事件
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
2.5 动画集合
1、使用PropertyValuesHolder
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX", 300f);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0f, 1f);
PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0f, 1f);
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, p1, p2, p3);
anim.setDuration(1000).start();
2、使用AnimatorSet
AnimatorSet可以实现更精确的顺序控制
playTogether(一起[təˈgeðə(r)]) 同时
playSequentially(顺序[sɪ'kwenʃəlɪ]) 顺序
animSet.play().with() 一起执行
defore()之前
after() 之后
ObjectAnimator a1 = ObjectAnimator.ofFloat(view, "translationX", 300f);
ObjectAnimator a2 = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0f, 1f);
ObjectAnimator a3 = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0f, 1f);
AnimatorSet set = new AnimatorSet();
set.setDuration(1000);
set.playTogether(a1, a2, a3);
set.start();
2.6 运行效果
三、源码
3.1 视图动画
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
findViewById(R.id.button3).setOnClickListener(this);
findViewById(R.id.button4).setOnClickListener(this);
findViewById(R.id.button5).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button:
AlphaAnimation aa = new AlphaAnimation(0, 1);// 从透明到不透明
aa.setDuration(1000);
v.startAnimation(aa);
break;
case R.id.button2:
// RotateAnimation ra = new RotateAnimation(0, 360, v.getWidth()/2, v.getHeight()/2);// 旋转开始角度结束角度,旋转中心
RotateAnimation ra = new RotateAnimation(0, 360, RotateAnimation.RELATIVE_TO_SELF, 0.5f ,
Animation.RELATIVE_TO_SELF, 0.5f);// 旋转开始角度结束角度,旋转中心
ra.setDuration(1000);
v.startAnimation(ra);
break;
case R.id.button3:
TranslateAnimation ta = new TranslateAnimation(0, 200, 0, 300);// x起动到终点 y起点到终点 相对值
ta.setDuration(1000);
v.startAnimation(ta);
break;
case R.id.button4:
// ScaleAnimation sa = new ScaleAnimation(0, 2, 0, 2);// 缩放倍数 缩放中心
ScaleAnimation sa = new ScaleAnimation(0, 2, 0, 2, ScaleAnimation.RELATIVE_TO_SELF, 0.5f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f);// 以自身为中心
sa.setDuration(1000);
v.startAnimation(sa);
break;
case R.id.button5:
AnimationSet as = new AnimationSet(true);
as.setDuration(1000);
AlphaAnimation a = new AlphaAnimation(0, 1);
a.setDuration(1000);
as.addAnimation(a);
TranslateAnimation t = new TranslateAnimation(0, 100, 0, 200);
t.setDuration(1000);
as.addAnimation(t);
v.startAnimation(as);
// 动画监听
as.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
break;
}
}
}
3.2 属性动画
public class ActivityAnimatorActivity extends Activity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animator);
findViewById(R.id.button6).setOnClickListener(this);
findViewById(R.id.button7).setOnClickListener(this);
findViewById(R.id.button8).setOnClickListener(this);
findViewById(R.id.button9).setOnClickListener(this);
findViewById(R.id.button10).setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.button6:
ObjectAnimator animator = ObjectAnimator.ofFloat(
view,
"translationX",
300
);
animator.setDuration(300);
animator.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) {
}
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
animator.start();
break;
case R.id.button7:
WrapperView wrapper = new WrapperView(view);
ObjectAnimator animator1 = ObjectAnimator.ofInt(wrapper, "width", 500);
animator1.setDuration(5000).start();
break;
case R.id.button8:
ValueAnimator animator2 = ValueAnimator.ofFloat(0, 100);
animator2.setTarget(view);
animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Float value = (Float) animation.getAnimatedValue();
System.out.println(value);
}
});
animator2.setDuration(1000).start();
break;
case R.id.button9:
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX", 300f);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0f, 1f);
PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0f, 1f);
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, p1, p2, p3);
anim.setDuration(1000).start();
break;
case R.id.button10:
ObjectAnimator a1 = ObjectAnimator.ofFloat(view, "translationX", 300f);
ObjectAnimator a2 = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0f, 1f);
ObjectAnimator a3 = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0f, 1f);
AnimatorSet set = new AnimatorSet();
set.setDuration(1000);
set.playTogether(a1, a2, a3);
set.start();
break;
}
}
private static class WrapperView{
private View mTarget;
public WrapperView(View target){
this.mTarget = target;
}
public int getWidth(){
return mTarget.getLayoutParams().width;
}
public void setWidth(int width){
mTarget.getLayoutParams().width = width;
mTarget.requestLayout();
}
}
}
浙公网安备 33010602011771号