Android属性动画
自Android 3.0版本开始,系统给我们提供了一种全新的动画模式,属性动画(property animation),它的功能非常强大,弥补了之前补间动画的一些缺陷,几乎是可以完全替代掉补间动画了。
属性动画与补间动画的区别
最大的区别是补间动画就算控件移动到任何位置,控件本身位置还是不变。而属性动画是直接改变控件的位置。
属性动画资源文件的常用属性
propertyName属性。动画类型名字
l "rotation" 自身平面旋转
l "rotationX" 3D翻转 X轴不变
l "rotationY" 3D翻转 Y轴不变
l "alpha" 透明度
l "scaleX" 缩放X 轴
l "scaleY" 缩放Y 轴
l "translationY" Y轴上移动
l "translationX" X轴上横向移动
现在通过一个案例来更了解属性动画的基本用法。
资源文件布局:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_my_animator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background_star"
tools:context="com.jogger.propertiesanim.MyAnimator">
<ImageView
android:visibility="invisible"
android:id="@+id/iv_star"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:src="@drawable/star"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="45dp"
android:text="轻触屏幕开始动画"
android:textColor="@color/colorPrimary"
android:textSize="20sp"/>
</RelativeLayout>
代码:
public class MyAnimator extends AppCompatActivity {
private RelativeLayout activity_my_animator;
private ImageView iv_star;
private TextView tv_msg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_animator);
activity_my_animator = (RelativeLayout) findViewById(R.id.activity_my_animator);
iv_star = (ImageView) findViewById(R.id.iv_star);
activity_my_animator.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//showStarAnim1();//对角线平移、缩放
//showStarAnim2();//平移--->缩放--->旋转并透明--->使用动画集
//showStarAnim3();//透明、旋转、平移
}
});
}
private void showStarAnim3() {
iv_star.setVisibility(View.VISIBLE);
iv_star.animate().alpha(0.1f).rotation(360).translationX(-400).setDuration(3000).start();
}
private void showStarAnim2() {
iv_star.setVisibility(View.VISIBLE);
//设置平移动画
ObjectAnimator transXAnim = ObjectAnimator.ofFloat(iv_star, "translationX", 0, -400);
transXAnim.setDuration(5000);
//设置缩放动画
ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(iv_star, "scaleX", 0.2f, 1);
scaleXAnim.setDuration(3000);
ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(iv_star, "scaleY", 0.2f, 1);
scaleYAnim.setDuration(3000);
//设置旋转动画
ObjectAnimator rotateAnim = ObjectAnimator.ofFloat(iv_star, "rotation", 0, 360);
rotateAnim.setDuration(3000);
//set.play(transXAnim).before(rotateAnim).after(scaleXAnim).with(scaleYAnim);
AnimatorSet set = new AnimatorSet();
//平移--->缩放--->旋转(缩放在旋转之前,平移之后)
set.play(scaleXAnim).with(scaleYAnim).before(rotateAnim).after(transXAnim);
rotateAnim.addListener(new AnimatorListenerAdapter() {//添加动画监听
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
ObjectAnimator alphaAnim=ObjectAnimator.ofFloat(iv_star,"alpha",1,0.1f);
alphaAnim.setDuration(3000);
alphaAnim.start();
}
});
set.start();
}
private void showStarAnim1() {
iv_star.setVisibility(View.VISIBLE);
int endX = getResources().getDisplayMetrics().widthPixels - iv_star.getMeasuredWidth();
//设置X轴平移量
int endY = getResources().getDisplayMetrics().heightPixels - iv_star.getMeasuredHeight()
* 2;
//设置Y轴平移量
PropertyValuesHolder transXHolder = PropertyValuesHolder.ofFloat("translationX", 0, -endX);
PropertyValuesHolder transYHolder = PropertyValuesHolder.ofFloat("translationY", 0, endY);
PropertyValuesHolder scaleXHolder=PropertyValuesHolder.ofFloat("scaleX",1,0);
PropertyValuesHolder scaleYHolder=PropertyValuesHolder.ofFloat("scaleY",1,0);
ObjectAnimator objectAnimator=ObjectAnimator.ofPropertyValuesHolder(iv_star,transXHolder,transYHolder,scaleXHolder,scaleYHolder);
objectAnimator.setDuration(3000);
objectAnimator.start();//播放完后,图片会回到原来的位置
}
}
这个代码块提供了3个演示属性动画的3个方法,效果如下:
showStarAnim1()的效果:
showStarAnim2()的效果:
showStarAnim3()的效果:
方法一使用的是PropertyValuesHolder,调用ofFloat()方法,参数一传入要操作的属性,参数二和参数三分别表示操作量的变化,然后使用objectAnimator对象的ofPropertyValuesHolder方法,传入要作用的对象,这里即星型图片,后面接的是可变参数,再把之前设置的PropertyValuesHolder放入即可。这个方法播放的动画结束后控件会回到最初的位置。
方法二使用的是set集合,通过ObjectAnimator的ofFloat()方法传入三个参数,分别表示作用的对象、操作属性、操作量的变化。然后创建AnimatorSet对象,通过play()、with()、before()、after()等方法对动画效果进行控制,后面的方法均以play()里的对象为准,这里要展示的效果是平移--->缩放--->旋转并透明,透明并不能直接使用with()加到旋转后面,因为都是以play里的对象(这里是缩放)为准的,所以如果放后面,为跟着缩放的同时一起播放,因此,要达到要求的效果,需要在旋转动画时添加监听,在旋转动画开始时去播放透明动画。
方法三是直接使用操作对象的animate()方法去调用要操作的动画,这样可以满足一些简单的操作需求,动画是同时播放的,并且不能设置初始值,一切初始值均以控件对象本身为准。
属性动画的xml文件实现:
第一步:在res/animator目录下创建文件anim_file.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<!--动画执行顺序 sequentially:顺序执行;together:同时执行。 -->
<objectAnimator
android:propertyName="translationX"
android:valueFrom="0"
android:valueTo="200"
android:duration="2000"
android:valueType="floatType" />
<set android:ordering="together">
<objectAnimator
android:propertyName="scaleX"
android:valueFrom="1"
android:valueTo="2"
android:duration="2000"
android:valueType="floatType" />
<objectAnimator
android:propertyName="rotationX"
android:valueFrom="0"
android:valueTo="90"
android:duration="2000"
android:valueType="floatType" /><!--动画值的类型-->
</set>
</set>
第二步,在代码中加载动画文件
Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_file);
animator.setTarget(view);
animator.start();
ordering表示的时播放方式,有按顺序播放和同时播放两种方式,propertyName即设置操作的属性,之后只需在代码块通过AnimatorInflater.loadAnimator加载属性动画的资源文件,用setTarget()方法设置到用作用的控件对象,在start()播放即可。