您的位置:首页 > 其它

安卓属性动画

2015-12-23 16:35 344 查看
在之前对于动画一直都是用Animation框架去实现的但是Animation有一个缺陷,就是动画交互事件的处理,Animation对于动画的操作是不断的去onDraw会导致我们无法监听到实时的动画事件,于是3.0之后有了属性动画Animator

-------------------------------------------------------------------------------------------------------------

原来我们实现一个简单动画的过程

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:src="@mipmap/ic_launcher"
android:onClick="click"
/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="move"
android:id="@+id/button"
android:onClick="move"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="同步"
android:onClick="playSynchronizing"
android:id="@+id/button2"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@+id/button"
android:layout_toEndOf="@+id/button" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="先后"
android:onClick="playUnsynchronizing"
android:id="@+id/button3"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@+id/button2"
android:layout_toEndOf="@+id/button2" />
</RelativeLayout>


我们对这个ImageView进行操作,现在想让ImageView沿X轴向右移动300

代码如下

public void move(View view){
<span style="white-space:pre">	</span>ImageView mImageView = (ImageView) findViewById(R.id.imageView);
Animation mAnimation = new TranslateAnimation(0,300,0,0);
mAnimation.setDuration(2000);
mAnimation.setFillAfter(true);//结束停留在结束位置
mImageView.startAnimation(mAnimation);
}
这样可以实现从左往右移动300

但是假设我们对这个imageView进行交互事件的监听会发现在ImageView移动完成之后我们点击ImageView无法触发上面的监听事件,但是我们点击动画的初始位置却能监听到

如图,一开始我们点击图片



这个时候是能监听到我们图片的点击事件,但是....当动画结束的时候我们点击动画



这个时候没有触发监听事件,只有当我们点击动画初始位置的时候才能触发监听事件

因为Animation动画框架改变的只是显示,并不能实现交互,因此有了Animator

-----------------------------------------------------------------------------------------

在Animator中使用比较多的是AnimatorSet和ObjectAnimator的配合,使用ObjectAnimator可以进行很精细的控制,只控制一个对象的属性值,而使用多个ObjectAnimator组合到AnimatorSet可以形成一个完成的动画,ObjectAnimator能够自行驱动,最重要的是属性动画通过调用属性的set,get方法来真实的控制了一个View的属性值.

ObjectAnimator是属性动画的实行类

ObjectAnimator animator1 = ObjectAnimator.ofFloat(mImageView,"translationX",0f,300f);//沿X平移
第一个参数传入你的target.就是想要进行变化的对象.第二个是对象的属性名字(必须有get,set方法)

在内部会通过反射去修改对象的属性值

启动动画:

animator1.setDuration(2000);
animatio1.start();
在进行操作的时候,操作的属性必须有get,set方法,不然objectAnimator无法生效.以下列举常用的属性:

translationX,translationY:控制View从它布局的左上角坐标开始位置

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

scaleX,scaleY:这两个属性控制着View对象的支点位置,围绕这个支点进行旋转缩放处理

X,Y:这是两个最简单的属性,它是translationX或者translationY的累积和

alpha:透明度 0~1

如果一个属性没有get,set方法我们可以自定义一个属性类并给属性添加get,set方法

public static class MyView{
public View mView;
public MyView(View target){
mView = target;
}
public int getWidth(){
return mView.getLayoutParams().width;
}
public int setWidth(int width){
mView.getLayoutParams().width = width;
mView.requestLayout();
}

}


调用:

MyView mMyView = new MyView(mImageView);
ObjectAnimator.ofInt(mMyView,"width",500).setDuration(1000).start();


-------------------------------------------------------------------

PropertyValuesHolder

类似视图动画的AnimationSet,如果针对同一个对象的多个属性,要同时作用多种动画,可以用PropertyValuesHolder实现

<span style="white-space:pre">	</span>PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("rotation",0f,720f);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translationX",0f,300f);
PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("translationY",0f,400f);
ObjectAnimator.ofPropertyValuesHolder(mImageView,p1,p2,p3).setDuration(2000).start();


这样就能同时启动三个动画作用于一个对象

AnimatorSet

public void playSynchronizing(View view){
ObjectAnimator animator1 = ObjectAnimator.ofFloat(mImageView,"translationX",0f,300f);//沿X平移
ObjectAnimator animator2 = ObjectAnimator.ofFloat(mImageView,"translationY",0f,300f);//沿y平移
ObjectAnimator animator3 = ObjectAnimator.ofFloat(mImageView,"rotation",0f,720f);//旋转
mSet = new AnimatorSet();
mSet.setDuration(2000);
mSet.playTogether(animator1,animator2,animator3);//同步执行动画
mSet.start();
}


这个会同时执行所有动画,如果要按照顺序执行的话

<pre name="code" class="java">   public void playSynchronizing(View view){
ObjectAnimator animator1 = ObjectAnimator.ofFloat(mImageView,"translationX",0f,300f);//沿X平移
ObjectAnimator animator2 = ObjectAnimator.ofFloat(mImageView,"translationY",0f,300f);//沿y平移
ObjectAnimator animator3 = ObjectAnimator.ofFloat(mImageView,"rotation",0f,720f);//旋转
mSet = new AnimatorSet();
mSet.setDuration(2000);
mSet.play(animator1).with(animator2);//先执行X,Y平移动画
mSet.play(animator3).after(animator2);//再执行旋转动画
mSet.start();
}



按照特定顺序执行
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: