您的位置:首页 > 移动开发 > Objective-C

属性动画:ObjectAnimator、PropertyValuesHolder、ValueAnimator、AnimatorSet

2016-09-04 02:32 609 查看
属性动画里涉及的一些属性值:

translationX和translationY: 这两个属性作为一种增量来控制着View对象从它布局容器的左上角坐标偏移的位置

rotation、rotationX和rotationY:这三个属性控制着View对象围绕支点进行2D和3D旋转

scaleX和scaleY:这两个属性控制着View对象围绕支点进行2D缩放

pivotX和pivotY:这两个属性控制着View对象的支点位置,围绕这个位置进行旋转和缩放的变化处理,默认情况下,该支点为View对象的中心点

x和y:这是两个简单实用的属性,它描述了View对象在它的容器中最终的位置,它是最初的左上角坐标和translationX、translationY值的累计和。

alpha:它表示View对象的alpha透明值,默认1不透明,0为完全透明

public class MainActivity extends AppCompatActivity {

ImageView image;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image =(ImageView)findViewById(R.id.image);
//        image.setAnimation(getTranslateAnimation());
//        UseValueAnimator();
UseAnimationSet(image);
}

/**
* 属性动画ObjectAnimator
* ObjectAnimator可以说是属性动画中使用最为广泛的一个类,它的三个参数分别代表着:
* view:作用的控件
* translationX:作用的属性
* 最后一个是可变数组参数
* @param view
* @return
*/
public ObjectAnimator getObjectAnimator(View view){
float tanslation=view.getTranslationX();
// ObjectAnimator animator=ObjectAnimator.ofFloat(view,"translationX",tanslation,-500f,3*tanslation);//左右移动
// ObjectAnimator animator=ObjectAnimator.ofFloat(view,"rotation",0,360);//围绕中心店或者X,Y轴做2D或3D旋转
// ObjectAnimator animator=ObjectAnimator.ofFloat(view,"scaleX",1f,5f,1f,3f);//围绕X或Y轴做2D缩放,1代表不缩放,后面的参数表示从1到5再到1再到3做缩放效果
ObjectAnimator animator=ObjectAnimator.ofFloat(view,"alpha",1f,0f,1f,0.5f);//透明值得变化 1表示不透明,0表示完全透明
animator.setDuration(3000);
//        animator.setRepeatCount(3);
animator.start();
return animator;
}

/**
* PropertyValuesHolder动画类似于视图动画中的AnimationSet,可针对一个view对象同时执行多个属性
* @param view
* @return
*/
public ObjectAnimator UseProPropertyValuesHolder(View view){
PropertyValuesHolder pvh1=PropertyValuesHolder.ofFloat("translationX", 300);
PropertyValuesHolder pvh3=PropertyValuesHolder.ofFloat("translationY",400);
PropertyValuesHolder pvh2=PropertyValuesHolder.ofFloat("rotationX",0,360);
ObjectAnimator animator=ObjectAnimator.ofPropertyValuesHolder(view, pvh1, pvh2, pvh3);
animator.setDuration(3000);
animator.setRepeatCount(2);
animator.start();
return animator;
}

/**
* ValueAnimator本身不提供动画效果,但是可用来监听一定规律的数字让调用者来控制动画的执行过程
* 通常情况下,使用AnimatorUpdateListener来监听数值的变化,从而完成动画的变换
* 常用方法有:
* public static ValueAnimator ofInt(int... values)
* public static ValueAnimator ofFloat(float... values)
* 以上的使用方法类似,只不过在做监听时返回的数据类型一个是int型一个是float型
* 以下使用的ofFloat(0, 300, 50, 400),数据变化从0到300再到50、400,然后通过使用layout来设置控件的位置,
* 从而达到动画的效果
* @return
*/
public ValueAnimator UseValueAnimator(){
ValueAnimator animator=ValueAnimator.ofFloat(0, 300, 50, 400);
//        animator.setTarget(image);
animator.setDuration(3000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Float value = (Float) animation.getAnimatedValue();
int viewXY = value.intValue();
image.layout(viewXY, viewXY, viewXY + image.getWidth(), viewXY + image.getHeight());
}
});
animator.start();
return animator;
}

/**
* 属性动画作用对个属性,与PropertyValuesHolder不同的是,PropertyValuesHolder是同时作用于多个动画,
* 而AnimatorSet是按着playTogether中参数的的位置来顺序执行的
* 在该AnimatorSet类中,通过使用其方法:set.playTogether()、set.playSequentially()等多个方法来协同工作
* 从而达到对动画的播放顺序进行精确的控制
* @param view
* @return
*/
public AnimatorSet UseAnimationSet(View view){
AnimatorSet set=new AnimatorSet();
ObjectAnimator animator1=ObjectAnimator.ofFloat(view,"translationX",300);
ObjectAnimator animator2=ObjectAnimator.ofFloat(view,"translationY",400);
ObjectAnimator animator3=ObjectAnimator.ofFloat(view,"scaleY",0,3,1);
set.setDuration(3000);
set.playTogether(animator1, animator2, animator3);
set.start();
return set;
}


动画的监听:

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) {

}
});


同样的,属性动画也是可以在XML中使用的,如下:

<animator> 对应代码中的ValueAnimator

<objectAnimator> 对应代码中的ObjectAnimator

<set> 对应代码中的AnimatorSet

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@[package:]anim/interpolator_resource"
android:shareInterpolator=["true" | "false"] >
<alpha
android:fromAlpha="float"
android:toAlpha="float" />
<scale
android:fromXScale="float"
android:toXScale="float"
android:fromYScale="float"
android:toYScale="float"
android:pivotX="float"
android:pivotY="float" />
<translate
android:fromXDelta="float"
android:toXDelta="float"
android:fromYDelta="float"
android:toYDelta="float" />
<rotate
android:fromDegrees="float"
android:toDegrees="float"
android:pivotX="float"
android:pivotY="float" />
<set>
...
</set>
</set>

   调用XML中定义的属性动画方法如下:

Animator animator= AnimatorInflater.loadAnimator(this,R.anim.myainm);
animator.setTarget(image);
animator.start();

    

在文章的开头讲了一些属性动画的属性值,这些属性值必须有对用的set和get函数,在调用时,内部会通过反射机制来调用set修改函数的对象属性值。在以上使用的view中之所以可以直接使用文章开头所讲的各个属性,是因为在View中已经设置了translationX、translationY、rotation···等这些属性的set和get方法。

   那么,当一个属性没有set和get方法时,如何继续使用属性动画呢? 这里有两种解决方式,一种是直接使用ValueAnimator,另一种就是以下的方式:

private static class MyView{
private View mview;
public  MyView(View view){
this.mview=view;
}
public int getWidth(){
return mview.getLayoutParams().width;
}
public void setWidth(int width){
mview.getLayoutParams().width=width;
mview.requestLayout();
}
}


    通过以上方式,就给一个属性包装了一层,并提供了get和set方法,使用时只需如下方式即可间接调用到set和get方法:

MyView myView=new MyView(image);
ObjectAnimator.ofInt(myView,"width",500).setDuration(3
ab89
000).start();

除了在以上方法使用属性动画以外,在3.0以后,View中也增加了animate方法来直接驱动属性动画,用法如下:

image.animate().alpha(0.5f).y(300).setDuration(3000).withStartAction(new Runnable() {
@Override
public void run() {

}
}).withEndAction(new Runnable() {
@Override
public void run() {

}
}).start();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐