前言:本篇文章参照以下文章学习整理1.http://blog.csdn.net/lmj623565791/article/details/38067475 2.http://blog.csdn.net/lmj623565791/article/details/38092093 3.http://blog.csdn.net/guolin_blog/article/details/43536355 4.http://blog.csdn.net/sinyu890807/article/details/43816093
一直想整理以下属性动画的知识,就是没有时间,所以一直拖着,不过最近工作中需要用到了,然并卵我还没整理所以被虐了一顿,赶紧回来整理了一番。
1.最简单的一个属性动画,代码如下:
private void objectAnimatorDemo(final ImageView image) {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(image, "rotationX", 0.0f, 180f);
objectAnimator.setDuration(3000);
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
((ImageView) findViewById(R.id.iv_showimage)).setImageBitmap(((BitmapDrawable) image.getDrawable()).getBitmap());//说明此动画是对view控件进行的动画操作,里面的bitmap并未进行任何变化
}
});
objectAnimator.start();
image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator
.ofFloat(image, "rotationY", 0f, 180f)
.setDuration(1000)
.start();
}
});
}
这里我需要整理三点,第一ofFloat方法中的参数问题,第一个参数是target目标,也就是说需要作用在谁身上(注意不一定非要上view),第二个参数说实话可以随意写,但是如果说你作用的对象里面如果有此参数对应的get和set方法,那么他就是对该属性进行操作,不停的改变属性值,但是如果作用的对象里面没有呢,也没关系,不会报错的,那么只是对后面的参数进行一定规律的变化,所以我觉得更像是handler消息处理机制吧,所以我们如果有什么需要在某个时间段内定时对某对象进行操作,也可以使用此方法。第三就是这个方法是对作用的对象进行的操作,因此其他内容不会改变,例如我们例子是对imageview进行的操作,因此视图是变化了但是里面的bitmap并没有发生任何改变。
2.一个简单的自定义动画集合
private void animatorSetDemo(final ImageView image) {
ObjectAnimator objectAnimator = ObjectAnimator
.ofFloat(image, "zhq", 0.0f, 1.0f)//说明第二个参数可以随意给,我们需要的是第三个参数的值,就像一个handler
.setDuration(2000);
objectAnimator.start();
objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Float value = (Float) animation.getAnimatedValue();
image.setAlpha(value);
image.setScaleX(value);
image.setScaleY(value);
}
});
}
这个其实就验证了上面说的,我们完全是自定义的一个属性动画,第二个参数“zhq”就是我胡乱写的,根本找不到,不过没关系,我们用的是后面的值在一定的时间内的变化,然后不停的设置属性来改变视图的动画。
3.第一种属性动画集合(没什么好说的)
private void propertyValuesHolder(ImageView image) {
PropertyValuesHolder alphapv = PropertyValuesHolder.ofFloat("alpha", 1f, 0, 1f);
PropertyValuesHolder scalepvX = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);
PropertyValuesHolder scalepvY = PropertyValuesHolder.ofFloat("scaleY", 1f, 0f, 1f);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(image, alphapv, scalepvX, scalepvY);
objectAnimator.setDuration(5000).setRepeatCount(2);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.start();
}
4.第二种属性动画集合(一起执行)
private void animatorSetDemo1(ImageView image) {
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(image,"scaleX",1f,0f,1f);
ObjectAnimator objectAnimator1=ObjectAnimator.ofFloat(image,"scaleY",1f,0f,1f);
ObjectAnimator alpha=ObjectAnimator.ofFloat(image,"alpha",1f,0f,1f);
AnimatorSet animatorSet=new AnimatorSet();
animatorSet.setDuration(4000);
animatorSet.playTogether(objectAnimator,objectAnimator1,alpha);
animatorSet.setInterpolator(new LinearInterpolator());
animatorSet.start();
}
5.第二种属性动画集合(先后按顺序执行)
private void playWithAfter(ImageView image) {//旋转分为以x轴为中心,以Y轴为中心,以某一个点为中心旋转,缩放也是沿X轴缩放,沿Y轴缩放,沿某一个点缩放
ObjectAnimator rotateX=ObjectAnimator.ofFloat(image,"rotationX",0,180f,0);
rotateX.setDuration(3000);
ObjectAnimator rotateY=ObjectAnimator.ofFloat(image,"rotationY",0,180f,0f);
rotateY.setDuration(3000);
ObjectAnimator alpha=ObjectAnimator.ofFloat(image,"alpha",1f,0f,1f);
alpha.setDuration(2000);
ObjectAnimator scaleX=ObjectAnimator.ofFloat(image,"scaleX",1f,0f,1f);
ObjectAnimator scaleY=ObjectAnimator.ofFloat(image,"scaleY",1f,0f,1f);
scaleX.setDuration(3000);
scaleY.setDuration(3000);
//这是中心轴,默认为中心点,可以通过下面方法来改变,pivotX 和 pivotY:旋转的轴点和缩放的基准点,默认是View的中心点。
image.setPivotX(0);
image.setPivotY(0);
image.invalidate();
AnimatorSet animatorSet=new AnimatorSet();
animatorSet.play(rotateX).before(rotateY);//rotateX--->rotateY before 在他之前执行
animatorSet.play(rotateY).before(alpha);//rotateY-->alpha after 在他之后执行
animatorSet.play(scaleX).with(scaleY).after(alpha);//alpha-->scale with 同时执行
animatorSet.start();
}
6.xml文件中定义属性动画,建立一个animator文件夹(谷歌官方建议)
private void xmlTogetherAnimator(ImageView image) {
Animator animatorOut = AnimatorInflater.loadAnimator(this, R.animator.animator_together_out);
Animator animatorIn = AnimatorInflater.loadAnimator(this, R.animator.animator_together_in);
AnimatorSet animatorSet=new AnimatorSet();
animatorSet.play(animatorOut).before(animatorIn);
animatorSet.setTarget(image);
animatorSet.start();
}
xml文件如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together"
><!--一起执行-->
<objectAnimator android:propertyName="scaleX"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType"
android:duration="3000"
/>
<objectAnimator android:propertyName="scaleY"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType"
android:duration="3000"/>
<objectAnimator android:propertyName="alpha"
android:valueFrom="1"
android:valueTo="0"
android:duration="3000"
android:valueType="floatType"/>
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together"
><!--一起执行-->
<objectAnimator android:propertyName="scaleX"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType"
android:duration="3000"
/>
<objectAnimator android:propertyName="scaleY"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType"
android:duration="3000"/>
<objectAnimator android:propertyName="alpha"
android:valueFrom="0"
android:valueTo="1"
android:duration="3000"
android:valueType="floatType"/>
</set>
这里想说明的是两个ordering参数:together 一起执行,sequentially按顺序执行
6.平移属性动画
private void translationAnimator(final ImageView image) {//平移分沿X轴平移,沿Y轴平移
float x = image.getTranslationX();
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(image,"translationX",x,x-200,x);
objectAnimator.setDuration(4000);
objectAnimator.setRepeatCount(1);
objectAnimator.setRepeatMode(ValueAnimator.RESTART);
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
ObjectAnimator rotate=ObjectAnimator.ofFloat(image,"rotation",0f,360f);
rotate.setDuration(3000);
rotate.start();
}
});
objectAnimator.start();
}
这里为什么单独把他拿出来呢,因为他很特殊,特别是参数求值方法很特殊,所以单独拿出来记一下。
7.根据大神的文章呢,理解了一下为什么ofFloat方法会执行,因为他用了一个FloatEnvalutor,顾名思义就是算法用的float类型的cost算法的计算方法。所以我们也可以自己定义一个按照我们的算法的一个envalutor:
/**
* 这里做一个简单的例子
* TypeEvaluator 指明我们需要操控计算的东西
* Interpolator 计算的规则
*/
class MyTypeEnvluator implements TypeEvaluator<Point>{
@Override
public Point evaluate(float fraction, Point startValue, Point endValue) {//三个参数的意思,fraction 完成度,startValue 开始值,endValue结束值,因此当前值为fraction*(endvalue-startvalue)+startvalue
int x= (int) (startValue.getX()+fraction*(endValue.x-startValue.x));
int y= (int) (startValue.getY()+fraction*(endValue.y-startValue.y));
return new Point(x,y);
}
}
class Point{
private int x;
private int y;
public Point(int x,int y){
this.x=x;
this.y=y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
用法就是objectanimator.setEvaluator();
8.最后有一个简化的转为view设计的属性动画:
/**
* Android3.1新增加的属性动画,只针对view增加使用的简单方法 ViewPropertyAnimator
* @param image
*/
private void newApiAnimator(ImageView image) {
image.animate().rotation(360).setDuration(5000);//旋转动画,就是这么简单
}