1 package com.example.donghuatest;
2
3 import android.animation.ObjectAnimator;
4 import android.animation.PropertyValuesHolder;
5 import android.animation.ValueAnimator;
6 import android.animation.ValueAnimator.AnimatorUpdateListener;
7 import android.app.Activity;
8 import android.os.Bundle;
9 import android.view.View;
10 import android.widget.ImageView;
11
12 public class MainActivity extends Activity {
13
14 // 比較簡單的屬性動畫
15 private ObjectAnimator alphaAnimation = new ObjectAnimator();
16
17 private ImageView imageView;
18
19 @Override
20 protected void onCreate(Bundle savedInstanceState) {
21 super.onCreate(savedInstanceState);
22 setContentView(R.layout.activity_main);
23
24 imageView = (ImageView) this.findViewById(R.id.iv);
25 imageView.setOnClickListener(new View.OnClickListener() {
26
27 @Override
28 public void onClick(final View v) {
29 rotateyAnimRunFirst(v);
30 // rotateyAnimRunSecond(v);
31 // rotateyAnimRunThird(v);
32 }
33 });
34
35 }
36
37 /**
38 * 橫向翻轉 Y軸不變
39 *
40 * @param view
41 */
42 public void rotateyAnimRunFirst(final View view) {
43 ObjectAnimator anim = ObjectAnimator.ofFloat(view, "rotationY", 0.0F,
44 360.0F).setDuration(500);
45 anim.start();
46 }
47
48 /**
49 * 讓這個圖片由大變小 並且透明度也有變化 注意這個透明度變化到0的時候就結束了 並沒有回復到初始狀態
50 *
51 * @param view
52 */
53 public void rotateyAnimRunSecond(final View view) {
54 ObjectAnimator anim = ObjectAnimator.ofFloat(view, "zhy", 1.0F, 0.0F)
55 .setDuration(500);
56 anim.start();
57 anim.addUpdateListener(new AnimatorUpdateListener() {
58 @Override
59 public void onAnimationUpdate(ValueAnimator animation) {
60 float cVal = (Float) animation.getAnimatedValue();
61 view.setAlpha(cVal);
62 view.setScaleX(cVal);
63 view.setScaleY(cVal);
64 }
65 });
66
67 }
68
69 /**
70 * 另外一種一個動畫 包含多種效果的方法 也更加方便 和第二個相比 他最終的結果仍是初始化的結果
71 *
72 * @param view
73 */
74 public void rotateyAnimRunThird(final View view) {
75 PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,
76 0f, 1f);
77 PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f,
78 0, 1f);
79 PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f,
80 0, 1f);
81 ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY, pvhZ)
82 .setDuration(1000).start();
83
84 }
85
86 }
這是寫的一個屬性動畫的小demo,大家可以跑起來運行一下,總共有3個效果。
rotateyAnimRunFirst 這個函數 其實主要就是一個翻轉的效果。
rotateyAnimRunSecond 這個函數 就是把圖片從大到小變化一次 ,並且透明度也有變化。 相當於是一個混合的動畫效果
rotateyAnimRunThird 這個函數和上面第二個函數效果其實差不多,只不過 這個到最後會回復到一開始的效果,並且用的方法也不一樣。
其實這個屬性動畫,也是很好理解的,相對於其他兩種動畫來說,屬性動畫更改的是view 本身。
rotateyAnimRunFirst 這個函數 裡面可以看到 傳進去了
rotationY 這個值,到這裡很多人就要問,這個地方的值要傳什麼,其實這個地方很好理解。對於第一種函數的 調用方式來說
你傳什麼值,這個屬性動畫就更改什麼值,當然前提是這個值的 get set方法 必須有。
你如果傳的值 沒有get set方法的話 那這個屬性動畫 肯定是不起作用的。
比如我們這裡的代碼是更改的imageview 我們可以看一下 imageview 繼承自 view
而view裡面 是有這些get set方法的
1 float mRotationY = 0f;
2
3 /**
4 * The degrees rotation around the horizontal axis through the pivot point.
5 */
6 @ViewDebug.ExportedProperty
7 float mRotationX = 0f;
8
9 /**
10 * The degrees rotation around the pivot point.
11 */
12 @ViewDebug.ExportedProperty
13 float mRotation = 0f;
14
15 /**
16 * The amount of translation of the object away from its left property (post-layout).
17 */
18 @ViewDebug.ExportedProperty
19 float mTranslationX = 0f;
20
21 /**
/**
* The degrees that the view is rotated around the vertical axis through the pivot point.
*
* @see #getPivotX()
* @see #getPivotY()
* @see #setRotationY(float)
*
* @return The degrees of Y rotation.
*/
public float getRotationY() {
return mTransformationInfo != null ? mTransformationInfo.mRotationY : 0;
}
所以我們的first函數 是肯定可以執行成功的。
然後我們來看second函數。
anim.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float cVal = (Float) animation.getAnimatedValue();
view.setAlpha(cVal);
view.setScaleX(cVal);
view.setScaleY(cVal);
}
});
著重看這裡,其實也就猜到了,對於第二種函數的屬性動畫調用來說, 我們是自己去控制的。
float cVal = (Float) animation.getAnimatedValue();
view.setAlpha(cVal);
view.setScaleX(cVal);
view.setScaleY(cVal);
這邊取得值以後 就自己更改v的屬性了~~~很容易理解。
所以實際上這裡的代碼 還可以這麼寫
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "tttt", 1.0F, 0.0F)
.setDuration(500);
那個tttt 還可以改成你任意想改的名字 對結果沒有影響,因為最終是我們手動用回調函數去更改view
的屬性的,這個過程是我們自己寫的,所以這裡名字可以隨便寫,而first函數 則不可以 因為是
系統自己通過反射去調用set get方法的,所以傳值的時候要注意~~
最後一個函數 third函數 其實就是把系統裡面自己實現的過程給單拿出來 罷了 不信我們可以跟蹤源代碼
ObjectAnimator 裡的這個函數
/**
* Constructs and returns an ObjectAnimator that animates between float values. A single
* value implies that that value is the one being animated to. Two values imply a starting
* and ending values. More than two values imply a starting value, values to animate through
* along the way, and an ending value (these values will be distributed evenly across
* the duration of the animation).
*
* @param target The object whose property is to be animated. This object should
* have a public method on it called <code>setName()</code>, where <code>name</code> is
* the value of the <code>propertyName</code> parameter.
* @param propertyName The name of the property being animated.
* @param values A set of values that the animation will animate between over time.
* @return An ObjectAnimator object that is set up to animate between the given values.
*/
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {
ObjectAnimator anim = new ObjectAnimator(target, propertyName);
anim.setFloatValues(values);
return anim;
}
然後繼續跟。
/**
* Sets the values, per property, being animated between. This function is called internally
* by the constructors of ValueAnimator that take a list of values. But an ValueAnimator can
* be constructed without values and this method can be called to set the values manually
* instead.
*
* @param values The set of values, per property, being animated between.
*/
public void setValues(PropertyValuesHolder... values) {
int numValues = values.length;
mValues = values;
mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
for (int i = 0; i < numValues; ++i) {
PropertyValuesHolder valuesHolder = (PropertyValuesHolder) values[i];
mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
}
// New property/values/target should cause re-initialization prior to starting
mInitialized = false;
}
@Override
public void setFloatValues(float... values) {
if (mValues == null || mValues.length == 0) {
// No values yet - this animator is being constructed piecemeal. Init the values with
// whatever the current propertyName is
if (mProperty != null) {
setValues(PropertyValuesHolder.ofFloat(mProperty, values));
} else {
setValues(PropertyValuesHolder.ofFloat(mPropertyName, values));
}
} else {
super.setFloatValues(values);
}
}
然後我們third函數裡面調用的方法
ofPropertyValuesHolder
/**
* Constructs and returns an ObjectAnimator that animates between the sets of values specified
* in <code>PropertyValueHolder</code> objects. This variant should be used when animating
* several properties at once with the same ObjectAnimator, since PropertyValuesHolder allows
* you to associate a set of animation values with a property name.
*
* @param target The object whose property is to be animated. Depending on how the
* PropertyValuesObjects were constructed, the target object should either have the {@link
* android.util.Property} objects used to construct the PropertyValuesHolder objects or (if the
* PropertyValuesHOlder objects were created with property names) the target object should have
* public methods on it called <code>setName()</code>, where <code>name</code> is the name of
* the property passed in as the <code>propertyName</code> parameter for each of the
* PropertyValuesHolder objects.
* @param values A set of PropertyValuesHolder objects whose values will be animated between
* over time.
* @return An ObjectAnimator object that is set up to animate between the given values.
*/
public static ObjectAnimator ofPropertyValuesHolder(Object target,
PropertyValuesHolder... values) {
ObjectAnimator anim = new ObjectAnimator();
anim.mTarget = target;
anim.setValues(values);
return anim;
最終也是通過 setValues 這個方法來做的。