今天讲解的是ObjectAnimator。
上一章节已经讲解了ValueAnimator,还不熟悉ValueAnimator的可以先去看上一章。ObjectAnimator继承自ValueAnimator,ValueAnimator的用法ObjectAnimator也可以用。
还是从基本的讲起。看代码:
ObjectAnimator offObject = ObjectAnimator.ofFloat(imageView, "scaleX", 0, 1f);
offObject.setDuration(1000);
offObject.start();
效果为:
这例子中,不必像上一章里的ValueAnimator中的addUpdateListener中手动设置值。ObjectAnimator通过反射会调用setXXX()方法,XXX在这个例子中是ScaleX。如果你属性的set方法中没有调用重绘,你必须像上一章ValueAnimator一样在addUpdateListener中手动调用该对象的重绘方法。在后面,我会通过一个自定义的view来说明具体细节。先一点一点往后说。
分开设置:
/ 也可以分开设置
final ObjectAnimator offObject = new ObjectAnimator();
offObject.setTarget(imageView);
offObject.setPropertyName("scaleX");
offObject.setFloatValues(1f,0.0f);
offObject.start();
同时还可以做updateListener:
<pre name="code" class="java">offObject.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
ImageView image = (ImageView) offObject.getTarget(); //得到设置的target对象
image.setPivotX(0); //设置缩放点中心
image.setAlpha((Float) animation.getAnimatedValue());
}
});
不同于ValueAnimator,可以通过objectAnimator.getTarget()得到你设置的对象。 我们还可以加动画的状态监听。
offObject.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
Toast.makeText(ObjectActivity.this,"offObject1开始",Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationEnd(Animator animation) {
Toast.makeText(ObjectActivity.this,"offObject1结束",Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
//
offObject.start(); //要想onAnimationStart能执行,start()必须在addListener()后
只要是animator都可以加,看效果。
接下来结束AnimatorSet。
不多说,直接上代码:ObjectAnimator offObject1 = ObjectAnimator.ofFloat(imageView, "scaleX", 0, 1f);
ObjectAnimator offObject2 = ObjectAnimator.ofFloat(imageView, "scaleY", 1f, 2f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(1000);
// animatorSet.playTogether(offObject1,offObject2); //两个动画同时执行
// animatorSet.play(offObject1).with(offObject2); //两个动画同时执行
animatorSet.play(offObject1).before(offObject2); //1在2之前
// animatorSet.play(offObject1).after(offObject2); //1在2之后
animatorSet.start();
animatorSet.addListener(new AnimatorListenerAdapter(){
@Override
public void onAnimationEnd(Animator animation){
Toast.makeText(ObjectActivity.this,"animatorSet结束",Toast.LENGTH_SHORT).show();
}
});
这里的AnimatorListenerAdapter空实现了AnimatorListener,可以只用写你想用的部分。
效果图:
使用PropertyValuesHolder
上一章说过PropertyValuesHolder常用在ObjectAnimator。看代码:
//使用PropertyValuesHolder
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("scaleX",0,1f);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("scaleY",1f,2f);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(imageView,p1,p2);
objectAnimator.setDuration(1000);
objectAnimator.start();
xml加载动画
首先在res目录下新建一个animator目录,然后在该目录中新建xml文件,下面代码的文件命名为object_x1。<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially"
>
<!-- android:ordering="sequentially" sequentially顺序的执行,还有个together
-->
<!-- android:duration="1000" 写在上面的set中代表整个时长为1秒
写在下面的animator中表示单个animator的时长-->
<objectAnimator
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="0"
android:valueTo="1.0" >
</objectAnimator>
<objectAnimator
android:duration="5000"
android:propertyName="scaleY"
android:valueFrom="1"
android:valueTo="2.0" >
</objectAnimator>
</set>
在activity中:
//xml加载动画
Animator animator = AnimatorInflater.loadAnimator(this,R.animator.object_x1);
animator.setTarget(imageView);
animator.start();
最后,我们自定义一个view,并对该view实行属性动画
自定义view的代码:
package com.example.animator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by xiaoshengke on 2015/6/18.
*/
public class LineView extends View {
/**
* 线的宽度
*/
private float paintWidth;
private Paint paint;
public LineView(Context context) {
super(context);
}
public LineView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LineView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public float getPaintWidth() {
return paintWidth;
}
public void setPaintWidth(float paintWidth) {// animator在每一帧绘制时会通过反射调用该方法。
this.paintWidth = paintWidth;
invalidate(); //如果没写该方法,在AnimatorUpdateListener的onAnimationUpdate中调用该view的invalidate()方法
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(paintWidth);
paint.setColor(0xffff6688);
canvas.drawLine(50,50,200,50,paint);
}
}
这里也就是定义了下画笔的宽度,然后画一条线。
点击这条线,看效果:
源码http://yunpan.cn/cwebQmG9jhNPh (提取码:9408)