最近在看Android群英传,主要针对Android群英传中的介绍,对Android中属性动画进行概括一下。
相比于视图动画,属性动画的一个最大的优点就是动画可以响应事件,最常使用的几个类:
ObjectAnimator, PropertyValuesHolder,ValueAnimator,AnimatorSet
ObjectAnimator是属性动画中最重要的实行类,,创建一个ObjectAnimator只需要通过静态的工厂类直接返回一个ObjectAnimator 对象。
ObjectAnimator animator=ObjectAnimator.ofFloat(imageView,"alpha",1F,0F);
animator.setDuration(500);
animator.start();
第一个是要操作的view,这里是一个ImageView;第二个是要操作的属性,主要有translationX,translationY
rotationX,rotationY,scaleX,scaleY,alpha 等;第三个是可变数组参数,属性变化的取值,只有一个是最终的属性值,两个的时候是起始属性值和最终的属性值。
需要注意的一点:操作的属性必须要有get,set方法(原因:有get set方法 可以通过Java反射机制来调用set函数修改对象的属性值),没有get set方法怎么办?两种解决方法:1.自定义属性类 2.使用ValueAnimator(后面有介绍)
上面提到动画的属性有多种,如何同时对一个对象的多个属性设置动画效果,这里可以采用 PropertyValuesHolder
例如:
PropertyValuesHolder pvh1=PropertyValuesHolder.ofFloat("translationX",300f);
PropertyValuesHolder pvh2=PropertyValuesHolder.ofFloat("scaleX",1f,0,1f);
PropertyValuesHolder pvh3=PropertyValuesHolder.ofFloat("scaleY",1f,0,1f);
ObjectAnimator.ofPropertyValuesHolder(imageView,pvh1,pvh2,pvh3).setDuration(1000).start();
调用ObjectAnimator.ofPropertyValuesHolder多属性动画的共同作用,类似于AnimationSet
书上说是属性动画的核心,ObjectAnimator继承自ValueAnimator
ValueAnimator不需要对象的属性有 get set 方法,它更像数值发生器,本身不提供动画效果,但产生一定规律的数字,从而控制动画的产生。通常情况下在ValueAnimator.AnimatorUpdateListener()监听数值的变换
ValueAnimator valueAnimator=ValueAnimator.ofInt(0,100);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
@Override
public void onAnimationUpdate(ValueAnimator animation) {
((TextView)view).setText("$"+(Integer)animation.getAnimatedValue());
}
});
valueAnimator.setDuration(3000);
valueAnimator.start();
和前面 PropertyValuesHolder一样,AnimatorSet可以实现多种属性动画的效果,不同之处就是可实现顺序的控制
ObjectAnimator animator1=ObjectAnimator.ofFloat(imageView,"translationX",300f);
ObjectAnimator animator2=ObjectAnimator.ofFloat(imageView,"scaleX",1f,0,1f);
ObjectAnimator animator3=ObjectAnimator.ofFloat(imageView,"scaleY",1f,0,1f);
AnimatorSet set=new AnimatorSet();
set.setDuration(1000);
set.playTogether(animator1, animator2, animator3);
//set.playSequentially(animator1, animator2, animator3);
set.play(animator1).with(animator2).before(animator3);
注意几个方法,playTogether,playSequentially,play( ).with( ),before( ),after( )
ObjectAnimator animator=ObjectAnimator.ofFloat(imageView,"alpha",1F,0F);
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) {
}
});
当只关心动画结束时的操作的时候,可以使用:
ObjectAnimator animator=ObjectAnimator.ofFloat(imageView,"alpha",1F,0F);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
下面是两个例子:
第一个使用ObjectAnimator和AnimatorSet 效果图 1,2 第二个是使用ValueAnimator(注释部分)效果图是3
效果图:
布局文件xml:
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView_b" android:src="@drawable/b" android:layout_centerVertical="true" android:layout_centerHorizontal="true" />
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView_c" android:src="@drawable/c" android:layout_centerVertical="true" android:layout_centerHorizontal="true" />
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView_d" android:src="@drawable/d" android:layout_centerVertical="true" android:layout_centerHorizontal="true" />
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView_e" android:src="@drawable/e" android:layout_centerVertical="true" android:layout_centerHorizontal="true" />
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView_a" android:src="@drawable/a" android:layout_centerVertical="true" android:layout_centerHorizontal="true" />
</RelativeLayout>
MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private int[] mRes={R.id.imageView_a,R.id.imageView_b,R.id.imageView_c,R.id.imageView_d,R.id.imageView_e};
private List<ImageView> imageViews=new ArrayList<>();
private boolean mFlag=true;
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* for(int i=0;i<mRes.length;i++){ ImageView imageview=(ImageView)findViewById(mRes[i]); imageview.setOnClickListener(this); imageViews.add(imageview); }*/
textView= (TextView) findViewById(R.id.text);
textView.setOnClickListener(this);
}
public void tvTimer(final View view){
ValueAnimator valueAnimator=ValueAnimator.ofInt(0,100);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
@Override
public void onAnimationUpdate(ValueAnimator animation) {
((TextView)view).setText("$"+(Integer)animation.getAnimatedValue());
}
});
valueAnimator.setDuration(3000);
valueAnimator.start();
}
@Override
public void onClick(View v) {
/* switch (v.getId()){ case R.id.imageView_a: if(mFlag){ startAnim(); }else{ closeAnim(); } break; }*/
switch (v.getId()){
case R.id.text:
tvTimer(textView);
}
}
private void startAnim(){
ObjectAnimator animator0=ObjectAnimator.ofFloat(imageViews.get(0),"alpha",1F,0.5F);
ObjectAnimator animator1=ObjectAnimator.ofFloat(imageViews.get(1),"translationY",200F);
ObjectAnimator animator2=ObjectAnimator.ofFloat(imageViews.get(2),"translationX",200F);
ObjectAnimator animator3=ObjectAnimator.ofFloat(imageViews.get(3),"translationY",-200F);
ObjectAnimator animator4=ObjectAnimator.ofFloat(imageViews.get(4),"translationX",-200F);
AnimatorSet set=new AnimatorSet();
set.setDuration(500);
set.setInterpolator(new BounceInterpolator());
set.playTogether(animator0,animator1,animator2,animator3,animator4);
set.start();
mFlag=false;
}
private void closeAnim(){
ObjectAnimator animator0=ObjectAnimator.ofFloat(imageViews.get(0),"alpha",0.5F,1F);
ObjectAnimator animator1=ObjectAnimator.ofFloat(imageViews.get(1),"translationY",200F,0);
ObjectAnimator animator2=ObjectAnimator.ofFloat(imageViews.get(2),"translationX",200F,0);
ObjectAnimator animator3=ObjectAnimator.ofFloat(imageViews.get(3),"translationY",-200F,0);
ObjectAnimator animator4=ObjectAnimator.ofFloat(imageViews.get(4),"translationX",-200F,0);
AnimatorSet set=new AnimatorSet();
set.setDuration(500);
set.setInterpolator(new BounceInterpolator());
set.playTogether(animator0,animator1,animator2,animator3,animator4);
set.start();
mFlag=true;
}
}