特点:
- 改变的是对象的实际属性
- 不仅可以应用于View, 有getter和setter方法的都可以
在xml中定义
放在res\animator中
如:
animator_alpha.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:interpolator="@android:interpolator/accelerate_quad"
android:propertyName="alpha"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueFrom="1"
android:valueTo="0" />
animator_backgroud.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:propertyName="BackgroundColor"
android:repeatCount="infinite"
android:repeatMode="restart"
android:valueFrom="@color/colorAccent"
android:valueTo="@color/colorPrimary"
android:valueType="colorType" />
animator_set.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">// 动画顺序
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:interpolator="@android:interpolator/accelerate_quad"
android:propertyName="alpha"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueFrom="1"
android:valueTo="0" />
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:propertyName="BackgroundColor"
android:repeatCount="infinite"
android:repeatMode="restart"
android:valueFrom="@color/colorAccent"
android:valueTo="@color/colorPrimary"
android:valueType="colorType" />
</set>
作用于控件
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.animator_alpha);
animator.setTarget(mImage);
animator.start();
PropertyAnimXMLActivity
public class PropertyAnimXMLActivity extends AppCompatActivity {
private ImageView mImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_property_anim_xml);
mImage = (ImageView) findViewById(R.id.image);
}
public void onClick(View view) {
Animator animator;
switch (view.getId()) {
case R.id.btn_alpha:
animator = AnimatorInflater.loadAnimator(this, R.animator.animator_alpha);
break;
case R.id.btn_background:
animator = AnimatorInflater.loadAnimator(this, R.animator.animator_backgroud);
break;
case R.id.btn_set:
animator = AnimatorInflater.loadAnimator(this, R.animator.animator_set);
break;
default:
return;
}
animator.setTarget(mImage);
animator.start();
}
}
在Java代码中定义
PropertyAnimCodeActivity
public class PropertyAnimCodeActivity extends AppCompatActivity {
private ImageView mImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_property_anim_code);
mImage = (ImageView) findViewById(R.id.image);
}
public void onClick(View view) {
ObjectAnimator objectAnimator;
switch (view.getId()) {
case R.id.btn_alpha:
objectAnimator = ObjectAnimator.ofFloat(mImage, "alpha", 1, 0, 0.5f);
break;
case R.id.btn_translation:
objectAnimator = ObjectAnimator.ofFloat(mImage, "translationX", 0, 50, 20, 60,
30);
break;
case R.id.btn_rotate:
objectAnimator = ObjectAnimator.ofFloat(mImage, "rotation", 0, 360, 180, -180);
break;
case R.id.btn_scale:
objectAnimator = ObjectAnimator.ofFloat(mImage, "scaleX", 0, 1, 0, 2);
break;
case R.id.btn_background:
objectAnimator = ObjectAnimator.ofObject(mImage, "BackgroundColor",
new ArgbEvaluator(), Color.RED, Color.GRAY, Color.BLUE);
break;
case R.id.btn_set:
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator oaAlpha = ObjectAnimator.ofFloat(mImage, "scaleX", 0, 2);
ObjectAnimator oaScale = ObjectAnimator.ofFloat(mImage, "ScaleY", 0, 4);
//这里propertyName 首字母大小写都可以
animatorSet.setTarget(mImage);
animatorSet.setDuration(2000);
//同时执行:set.playTogether(animator1,animator2,animator3)
//顺序执行:set.playSequentially(animator1,animator2,animator3)
//分布执行:play().with(); play().after();
animatorSet.playTogether(oaAlpha, oaScale);
// after(Animator anim) 将现有动画插入到传入的动画之后执行
// after(long delay) 将现有动画延迟指定毫秒后执行
// before(Animator anim) 将现有动画插入到传入的动画之前执行
// with(Animator anim) 将现有动画和传入的动画同时执行
// animatorSet.play(oaAlpha).after(oaScale);
animatorSet.start();
//监听动画变化时四个状态
animatorSet.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) {
}
});
return;
default:
return;
}
objectAnimator.setRepeatCount(1);
objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
objectAnimator.setDuration(2000);
objectAnimator.start();
//监听动画变化时某个状态
//可以只复写部分方法, 这里传Animator.AnimatorListener的实现类AnimatorListenerAdapter
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
Toast.makeText(PropertyAnimCodeActivity.this, "动画结束", Toast.LENGTH_SHORT).show();
}
});
}
}
特别的地方
- 属性动画可以作用于任何有getter和setter方法的对象
- propertyName就是set开头的方法的方法名不包含”set” 第一个字母大小写可以随意,但后面的部分必须与set方法后的大小写保持一致。
- 可以使用Keyframe 时间/值 对定义属性动画, 可以理解为关键帧
PropertyAnimSpecialActivity
public class PropertyAnimSpecialActivity extends AppCompatActivity {
private TextView mTvTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_property_anim_special);
mTvTitle = (TextView) findViewById(R.id.tv_title);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_colorValue:
ObjectAnimator animator = ObjectAnimator.ofArgb(mTvTitle, "TextColor", Color.RED,
Color.YELLOW, Color.GREEN, Color.BLUE, Color.BLACK);
animator.setDuration(5000).start();
//监听动画变化时的实时值
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int currentTextColor = mTvTitle.getCurrentTextColor();
mTvTitle.setText("#" + Integer.toHexString(currentTextColor));
}
});
break;
case R.id.btn_value:
final Test target = new Test();
//propertyName就是set开头的方法的方法名不包含"set" 第一个字母大小写可以随意,但后面的部分必须与set方法后的大小写保持一致。
ObjectAnimator animator1 = ObjectAnimator.ofInt(target, "value", 0, 100000);
animator1.setDuration(5000).start();
animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//参数animation可以得到值
mTvTitle.setText(animation.getAnimatedValue() + "------" + target.getValue());
}
});
break;
case R.id.btn_keyFrames:
//The time, expressed as a value between 0 and 1
Keyframe keyframe1 = Keyframe.ofInt(0, R.color.colorAccent);
Keyframe keyframe2 = Keyframe.ofInt(0.25f, R.color.colorPrimary);
Keyframe keyframe3 = Keyframe.ofInt(0.5f, R.color.colorAccent);
Keyframe keyframe4 = Keyframe.ofInt(0.75f, R.color.colorPrimary);
Keyframe keyframe5 = Keyframe.ofInt(1.0f, R.color.colorAccent);
PropertyValuesHolder valuesHolder = PropertyValuesHolder.ofKeyframe("BackgroundResource", keyframe1, keyframe2, keyframe3,
keyframe4, keyframe5);
ObjectAnimator animator2 = ObjectAnimator.ofPropertyValuesHolder(mTvTitle, valuesHolder);
animator2.setDuration(3000).start();
break;
default:
break;
}
}
public class Test {
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
//可以得知, ObjectAnimator调用了set方法
// this.value = 666;
this.value = value;
}
}
}
源码参见: http://download.csdn.net/detail/maimiho/9660930
Android 动画总结-Activity切换动画 http://write.blog.csdn.net/mdeditor
Android 动画总结-Layout动画 http://blog.csdn.net/maimiho/article/details/52888887
Android 动画总结-帧动画 http://blog.csdn.net/maimiho/article/details/52893291
Android 动画总结-补间动画 http://blog.csdn.net/maimiho/article/details/52893403
Android 动画总结-属性动画 http://blog.csdn.net/maimiho/article/details/52894023
Android 动画总结-ViewPropertyAnimator http://blog.csdn.net/maimiho/article/details/52894151
Android 动画总结-矢量动画 http://blog.csdn.net/maimiho/article/details/52894266
作者:MAIMIHO 发表于2016/10/22 19:00:47 原文链接
阅读:105 评论:0 查看评论