今天抽空研究了一下Android 3.0 新增的Property Animation,官方文档链接地址:http://developer.android.com/guide/topics/graphics/prop-animation.html
首先我们要先了解关于View在3.0之后为了方便属性动画引入的几个新的属性:
translationX and translationY: These properties control where the View is located as a delta from its left and top coordinates which are set by its layout container.
rotation, rotationX, and rotationY: These properties control the rotation in 2D (rotation property) and 3D around the pivot point.
scaleX and scaleY: These properties control the 2D scaling of a View around its pivot point.
pivotX and pivotY: These properties control the location of the pivot point, around which the rotation and scaling transforms occur. By default, the pivot point is located at the center of the object.
x and y: These are simple utility properties to describe the final location of the View in its container, as a sum of the left and top values and translationX and translationY values.
alpha: Represents the alpha transparency on the View. This value is 1 (opaque) by default, with a value of 0 representing full transparency (not visible).
上面几段英文对应的翻译如下,水平有限,翻译的不准确的地方请多多包涵。
translationX 和 translationY:这两个属性控制了View所处的位置,它们的值是由layout容器设置的,是相对于坐标原点(0,0左上角)的一个偏移量。
rotation, rotationX 和 rotationY:控制View绕着轴点(pivotX和pivotY)2D、3D旋转。
scaleX 和 scaleY:控制View基于pivotX和pivotY的缩放。
pivotX 和 pivotY:旋转的轴点和缩放的基准点,默认是View的中心点。
x 和 y:描述了view在其父容器中的最终位置,是左上角左标和偏移量(translationX,translationY)的和。
aplha:代表透明度。默认值为1,1是完全不透明,0是完全透明。
这里将Property Animation涉及到的View属性总结成一个Demo,方便以后学习和复习。
Activity布局如下
<ScrollView 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" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" tools:context=".MainActivity" > <Button android:id="@+id/bt_alpha" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="透明" /> <Button android:id="@+id/bt_scaleX" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="scaleX" /> <Button android:id="@+id/bt_scaleY" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="scaleY" /> <Button android:id="@+id/bt_scaleXY" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="scaleXY" /> <Button android:id="@+id/bt_translationX" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="translationX" /> <Button android:id="@+id/bt_translationY" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="translationY" /> <Button android:id="@+id/bt_translationXY" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="translationXY" /> <Button android:id="@+id/bt_rotationX" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="rotationX" /> <Button android:id="@+id/bt_rotationY" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="rotationY" /> <Button android:id="@+id/bt_rotation" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="rotation" /> <Button android:id="@+id/bt_x" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="x" /> <Button android:id="@+id/bt_y" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="y" /> <Button android:id="@+id/bt_xy" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="xy" /> <Button android:id="@+id/bt_vpa" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="ViewPropAnimator" /> </LinearLayout> </ScrollView>
PropertyAnimationActivity 代码如下:
package com.example.propertyanimation; import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class PropertyAnimationActivity extends Activity implements OnClickListener { private static final String TAG = PropertyAnimationActivity.class.getSimpleName(); private Button bt_alpha; private Button bt_scaleX; private Button bt_scaleY; private Button bt_scaleXY; private Button bt_translationX; private Button bt_translationY; private Button bt_translationXY; private Button bt_rotationX; private Button bt_rotationY; private Button bt_rotation; private Button bt_vpa; private Button bt_x; private Button bt_y; private Button bt_xy; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_property); findView(); } private void findView() { bt_alpha = (Button) findViewById(R.id.bt_alpha); bt_scaleX = (Button) findViewById(R.id.bt_scaleX); bt_scaleY = (Button) findViewById(R.id.bt_scaleY); bt_scaleXY = (Button) findViewById(R.id.bt_scaleXY); bt_translationX = (Button) findViewById(R.id.bt_translationX); bt_translationY = (Button) findViewById(R.id.bt_translationY); bt_translationXY = (Button) findViewById(R.id.bt_translationXY); bt_rotationX = (Button) findViewById(R.id.bt_rotationX); bt_rotationY = (Button) findViewById(R.id.bt_rotationY); bt_rotation = (Button) findViewById(R.id.bt_rotation); bt_x = (Button) findViewById(R.id.bt_x); bt_y = (Button) findViewById(R.id.bt_y); bt_xy = (Button) findViewById(R.id.bt_xy); //ViewPropAnimator bt_vpa = (Button) findViewById(R.id.bt_vpa); bt_alpha.setOnClickListener(this); bt_scaleX.setOnClickListener(this); bt_scaleY.setOnClickListener(this); bt_scaleXY.setOnClickListener(this); bt_translationX.setOnClickListener(this); bt_translationY.setOnClickListener(this); bt_translationXY.setOnClickListener(this); bt_rotationX.setOnClickListener(this); bt_rotationY.setOnClickListener(this); bt_rotation.setOnClickListener(this); bt_x.setOnClickListener(this); bt_y.setOnClickListener(this); bt_xy.setOnClickListener(this); bt_vpa.setOnClickListener(this); } @SuppressLint("NewApi") @Override public void onClick(View v) { ObjectAnimator objectAnimator = null; switch (v.getId()) { case R.id.bt_alpha: objectAnimator = ObjectAnimator.ofFloat(bt_alpha, "alpha", 1f,0f); // objectAnimator.setTarget(bt_alpha); objectAnimator.setRepeatCount(1); objectAnimator.setRepeatMode(ValueAnimator.REVERSE); objectAnimator.setDuration(1000); objectAnimator.start(); break; case R.id.bt_scaleX: objectAnimator = ObjectAnimator.ofFloat(bt_scaleX, "scaleX", 1f,2f); objectAnimator.setRepeatCount(1); objectAnimator.setRepeatMode(ValueAnimator.REVERSE); objectAnimator.setDuration(1000); objectAnimator.start(); break; case R.id.bt_scaleY: objectAnimator = ObjectAnimator.ofFloat(bt_scaleY, "scaleY", 1f,2f); objectAnimator.setRepeatCount(1); objectAnimator.setRepeatMode(ValueAnimator.REVERSE); objectAnimator.setDuration(1000); objectAnimator.start(); break; case R.id.bt_scaleXY: AnimatorSet scaleSet = new AnimatorSet(); scaleSet.playTogether( ObjectAnimator.ofFloat(bt_scaleXY, "scaleX", 1, 1.5f), ObjectAnimator.ofFloat(bt_scaleXY, "scaleY", 1, 1.5f), ObjectAnimator.ofFloat(bt_scaleXY, "alpha", 1, 0.25f, 1) ); scaleSet.setDuration(4 * 1000).start(); break; case R.id.bt_translationX: objectAnimator = ObjectAnimator.ofFloat(bt_translationX, "translationX", 0,200); objectAnimator.setRepeatCount(1); objectAnimator.setRepeatMode(ValueAnimator.REVERSE); objectAnimator.setDuration(1000); objectAnimator.start(); break; case R.id.bt_translationY: objectAnimator = ObjectAnimator.ofFloat(bt_translationY, "translationY", 0f,200f); objectAnimator.setRepeatCount(1); objectAnimator.setRepeatMode(ValueAnimator.REVERSE); objectAnimator.setDuration(1000); objectAnimator.start(); break; case R.id.bt_translationXY: // AnimatorSet translationSet = new AnimatorSet(); // translationSet.playTogether( // ObjectAnimator.ofFloat(bt_translationXY, "translationX", 0, 200), // ObjectAnimator.ofFloat(bt_translationXY, "translationY", 0, 200), // ObjectAnimator.ofFloat(bt_translationXY, "alpha", 1, 0.25f, 1) // ); // translationSet.setDuration(4000).start(); //另一种实现方式 PropertyValuesHolder pvhtranslationX = PropertyValuesHolder.ofFloat("translationX",0f,150f); PropertyValuesHolder pvhtranslationY = PropertyValuesHolder.ofFloat("translationY",0f,150f); objectAnimator = ObjectAnimator.ofPropertyValuesHolder(bt_translationXY, pvhtranslationX,pvhtranslationY); objectAnimator.setRepeatCount(1); objectAnimator.setRepeatMode(ValueAnimator.REVERSE); objectAnimator.setDuration(2000); objectAnimator.start(); break; case R.id.bt_rotationX: objectAnimator = ObjectAnimator.ofFloat(bt_rotationX, "rotationX", 0f,300f); objectAnimator.setTarget(bt_rotationX); objectAnimator.setRepeatCount(1); objectAnimator.setRepeatMode(ValueAnimator.REVERSE); objectAnimator.setDuration(1000); objectAnimator.start(); break; case R.id.bt_rotationY: objectAnimator = ObjectAnimator.ofFloat(bt_rotationY, "rotationY", 0f,300f); objectAnimator.setTarget(bt_rotationY); objectAnimator.setRepeatCount(1); objectAnimator.setRepeatMode(ValueAnimator.REVERSE); objectAnimator.setDuration(1000); objectAnimator.start(); break; case R.id.bt_rotation: AnimatorSet rotationSet = new AnimatorSet(); rotationSet.playTogether( ObjectAnimator.ofFloat(bt_rotation, "rotationX", 0, 360), ObjectAnimator.ofFloat(bt_rotation, "rotationY", 0, 360) ); // rotationSet.playTogether( // ObjectAnimator.ofFloat(bt_rotation, "rotationX", 0, 360), // ObjectAnimator.ofFloat(bt_rotation, "rotationY", 0, 180), // ObjectAnimator.ofFloat(bt_rotation, "rotation", 0, -90) // ); rotationSet.setDuration(4 * 1000).start(); break; case R.id.bt_x: ObjectAnimator animX = ObjectAnimator.ofFloat(bt_x, "x", 50f); animX.setRepeatCount(1); animX.setRepeatMode(ValueAnimator.REVERSE); animX.setDuration(1000); animX.start(); break; case R.id.bt_y: ObjectAnimator animY = ObjectAnimator.ofFloat(bt_y, "y", 100f); animY.setRepeatCount(1); animY.setRepeatMode(ValueAnimator.REVERSE); animY.setDuration(1000); animY.start(); break; case R.id.bt_xy: PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f); ObjectAnimator animXY = ObjectAnimator.ofPropertyValuesHolder(bt_xy, pvhX, pvhY); animXY.setRepeatCount(1); animXY.setRepeatMode(ValueAnimator.REVERSE); animXY.setDuration(2000); animXY.start(); //另一种方式 ViewPropertyAnimator // bt_xy.animate().x(50f).y(100f).setDuration(2000).start(); break; case R.id.bt_vpa: bt_vpa.animate().alpha(0.2f).rotation(480f).setDuration(2000) .setListener(new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { // TODO Auto-generated method stub Log.e(TAG, "onAnimationStart"); } @Override public void onAnimationRepeat(Animator animation) { // TODO Auto-generated method stub Log.e(TAG, "onAnimationRepeat"); } @Override public void onAnimationEnd(Animator animation) { // TODO Auto-generated method stub Log.e(TAG, "onAnimationEnd"); } @Override public void onAnimationCancel(Animator animation) { // TODO Auto-generated method stub Log.e(TAG, "onAnimationCancel"); bt_vpa.animate().alpha(1f).rotation(240f).translationX(150).setDuration(2000).start(); } }) .start(); break; default: break; } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
我们也可以在XML文件中定义属性动画,语法如下:
具体用法可参考http://developer.android.com/guide/topics/resources/animation-resource.html
在res/animator/ 目录下,而不是之前的 res/anim/ 目录,如下
scalex.xml
<?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:propertyName="scaleX" android:duration="2000" android:valueFrom="1.0" android:valueTo="2.0" android:repeatCount="1" android:repeatMode="reverse"> </objectAnimator>
在代码中调用
animatorScaleSet = (AnimatorSet)AnimatorInflater.loadAnimator(this, R.animator.scale); animatorScaleSet.setTarget(btnScale); animatorScaleSet.start();
后期还会继续完善,有什么不对的地方还请大家指出来,Thx!