Android——属性动画(Property Animation)
最近在看Android群英传,主要针对Android群英传中的介绍,对Android中属性动画进行概括一下。
相比于视图动画,属性动画的一个最大的优点就是动画可以响应事件,最常使用的几个类:
ObjectAnimator, PropertyValuesHolder,ValueAnimator,AnimatorSet
ObjectAnimator
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
例如:
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
ValueAnimator
书上说是属性动画的核心,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();
AnimatorSet
和前面 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; }}
更多相关文章
- android中The connection to adb is down,问题和解决
- Android控件-多选按钮、单选按钮
- Android(安卓)Studio——Android(安卓)Studio更新升级方法
- android 布局文件中控件ID、name标签属性的命名包含“@”、“.”
- Android(安卓)ImageView的scaleType属性与adjustViewBounds属性
- 实现在一个界面里多个TextView的跑马灯效果
- Android(安卓)属性总结
- 浅谈Java中Collections.sort对List排序的两种方法
- Python list sort方法的具体使用