一. View 動(dòng)畫(huà)
分為四種:平移,縮放看彼,旋轉(zhuǎn)廊佩,漸變,他們之間有很多共性靖榕,所以有一個(gè)共同的父類(lèi) Animation标锄,存放一些動(dòng)畫(huà)共有的屬性
-
Animation
-
duration
時(shí)長(zhǎng) -
fillAfter
停止后是否留在最后一幀 -
fillBefore
停止后是否回到第一幀,默認(rèn)為 true -
fillEnabled
和fillBefore
相同 -
repeatCount
重復(fù)的次數(shù) -
repeatMode
重復(fù)的類(lèi)型序矩,分為reverse
和restart
鸯绿,前一個(gè)表示第一次動(dòng)畫(huà)結(jié)束后從最后一幀往前,后一個(gè)表示第一次動(dòng)畫(huà)結(jié)束后再?gòu)牡谝粠_(kāi)始簸淀,默認(rèn)是restart
-
interpolator
差值器
-
-
Translate 移動(dòng)
-
android:fromXDelta
數(shù)值可以為 整數(shù)瓶蝴,百分?jǐn)?shù),百分?jǐn)?shù)p 租幕,例如 50舷手、50%、50%p劲绪,- 50 表示以當(dāng)前View左上角坐標(biāo)加50px為初始點(diǎn)
- 50% 表示以當(dāng)前View的左上角加上當(dāng)前View寬高的50%做為初始點(diǎn)
- 50%p 表示以當(dāng)前View的左上角加上父控件寬高的50%做為初始點(diǎn)男窟,p 代表 parent
-
android:fromYDelta
同上 -
android:toXDelta
同上 -
android:toYDelta
同上
<?xml version="1.0" encoding="utf-8"?> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="0" android:fromYDelta="0" android:toXDelta="-80" android:toYDelta="-80" android:duration="2000"> </translate>
如果只是在 x 方向上移動(dòng)盆赤,不在 y 方向上移動(dòng),只需要寫(xiě)成下面這樣子, 不需要加上 y :
<?xml version="1.0" encoding="utf-8"?> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="0" android:toXDelta="-80" android:duration="2000"> </translate>
?
-
-
Scale 縮放放大
-
android:fromXScale
浮點(diǎn)值歉眷,開(kāi)始的時(shí)候 x方向 縮放或者放大比例 -
android:toXScale
浮點(diǎn)值牺六,結(jié)束的時(shí)候 x方向 縮放或者放大比例 -
android:fromYScale
同上x(chóng) -
android:toYScale
同上x(chóng) -
android:pivotX
軸點(diǎn) X 坐標(biāo),支持三種表示方式(數(shù)值汗捡,百分比淑际,父 View 百分比) -
android:pivotY
軸點(diǎn) Y 坐標(biāo)
-
-
Rotate 旋轉(zhuǎn)
-
android:fromDegrees
順時(shí)針正值,逆時(shí)針負(fù)值 android:toDegrees
-
android:pivotX
軸點(diǎn) X 坐標(biāo)扇住,支持三種表示方式 -
android:pivotY
軸點(diǎn) Y 坐標(biāo)
<?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="0" android:toDegrees="-650" android:pivotX="50%" android:pivotY="50%" android:duration="3000" android:fillAfter="true"> </rotate>
-
-
Alpha 漸變
-
android:fromAlpha
浮點(diǎn)值春缕,0.0 - 1.0, 0為全透明艘蹋,1位全不透明 android:toAlpha
<?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android="http://schemas.android.com/apk/res/android" android:fromAlpha="1.0" android:toAlpha="0.1" android:duration="3000" android:fillBefore="true"> </alpha>
-
-
Set 動(dòng)作合集
也是直接繼承自Animation
锄贼, 但是沒(méi)有自己的屬性,包裹其他動(dòng)畫(huà)女阀,實(shí)現(xiàn)幾個(gè)動(dòng)畫(huà)同時(shí)發(fā)生<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="3000" android:fillAfter="true"> <alpha android:fromAlpha="0.0" android:toAlpha="1.0"/> <scale android:fromXScale="0.0" android:toXScale="1.4" android:fromYScale="0.0" android:toYScale="1.4" android:pivotX="50%" android:pivotY="50%"/> <rotate android:fromDegrees="0" android:toDegrees="720" android:pivotX="50%" android:pivotY="50%"/> </set>
-
View 動(dòng)畫(huà)的使用
Animation translateAnim = AnimationUtils.loadAnimation(MainActivity.this, R.anim.translate); view.startAnimation(translateAnim);
二. 幀動(dòng)畫(huà)
幀動(dòng)畫(huà)的載體是一個(gè)
ImageViwe
宅荤, 設(shè)置一個(gè)AnimationDrawable
- 先定義一個(gè) animation-list 類(lèi)型的 xml 文件, 名字叫 item01 强品,放在 drawable 文件夾下面
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/anim_fram_08"
android:duration="80" />
<item
android:drawable="@drawable/anim_fram_09"
android:duration="80" />
<item
android:drawable="@drawable/anim_fram_10"
android:duration="80" />
</animation-list>
- 具體設(shè)置代碼:
ivAnim.setImageResource(R.drawable.item01);
AnimationDrawable animationDrawable = (AnimationDrawable) ivAnim.getDrawable();
animationDrawable.start();
三. 屬性動(dòng)畫(huà)
屬性動(dòng)畫(huà)原理是通過(guò)反射
setProp
方法不斷修改對(duì)象的屬性膘侮,例如 view 的 x 屬性值等屈糊,達(dá)到動(dòng)畫(huà)的效果的榛。
對(duì)于屬性值,只設(shè)置一個(gè)的時(shí)候逻锐,會(huì)認(rèn)為當(dāng)前對(duì)象該屬性的值為開(kāi)始(getPropName反射獲确蛏巍),然后設(shè)置的值為終點(diǎn)昧诱。如果設(shè)置兩個(gè)晓淀,則一個(gè)為開(kāi)始、一個(gè)為結(jié)束
動(dòng)畫(huà)更新的過(guò)程中盏档,會(huì)不斷調(diào)用setPropName更新元素的屬性凶掰,所有使用ObjectAnimator更新某個(gè)屬性,必須得有g(shù)etter(設(shè)置一個(gè)屬性值的時(shí)候)和setter方法
- ObjectAnimator
對(duì)象動(dòng)畫(huà)類(lèi)蜈亩,在構(gòu)造的過(guò)程中需要傳遞一個(gè)對(duì)象懦窘,主要通過(guò)of 方法
改變對(duì)象的屬性,因?yàn)槭?String 類(lèi)型的參數(shù)傳入稚配,所以沒(méi)有代碼提示畅涂,可以通過(guò)view.getXX
方法獲得具體的屬性名字和屬性的數(shù)據(jù)類(lèi)型,第三個(gè)參數(shù)可以設(shè)置多個(gè)參數(shù)值道川,標(biāo)識(shí)在這幾個(gè)參數(shù)之間變化, 例如下面就是先從 0 到 360午衰,再?gòu)?360 到 120立宜。
ObjectAnimator.ofFloat(view, "translationX", 0f, 360f,120f)
.setDuration(500)
.start();
Animator 有 addUpdateListener()
方法臊岸,用來(lái)設(shè)置在動(dòng)畫(huà)執(zhí)行過(guò)程中的回調(diào)監(jiān)聽(tīng)橙数。
例如下面,隨便設(shè)置了一個(gè)屬性帅戒,因?yàn)閷傩灾凳侵饾u變化的商模,變化的過(guò)程中會(huì)有觸發(fā)回調(diào),我們?cè)诨卣{(diào)里設(shè)置了scale 和 alpha 屬性
:
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "valuae", 1.0f, 0f, 1.0f)
.setDuration(1000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float animatValue = (float) animation.getAnimatedValue();
Log.i("value", animatValue + "");
view.setScaleX(animatValue);
view.setScaleY(animatValue);
view.setAlpha(animatValue);
}
});
animator.start();
PropertyValuesHolder
屬性持有器
用來(lái)保存一些屬性的變化過(guò)程蜘澜,構(gòu)造的時(shí)候只有屬性和變化的數(shù)值施流,方便組合動(dòng)畫(huà)
PropertyValuesHolder scaleXHolder = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0f, 1.0f);
PropertyValuesHolder scaleYHolder = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0f, 1.0f);
PropertyValuesHolder alphaHolder = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0f, 1.0f);
ObjectAnimator.ofPropertyValuesHolder(view, scaleXHolder, scaleYHolder, alphaHolder)
.setDuration(1000)
.start();
- ValueAnimator
構(gòu)造的時(shí)候只傳入變化的數(shù)值,然后在animator.addUpdateListener
中根據(jù)動(dòng)畫(huà)的數(shù)值手動(dòng)進(jìn)行動(dòng)畫(huà)
ValueAnimator valueAnimator = ValueAnimator.ofFloat(1.0f, 0f, 1.0f);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
view.setScaleX(value);
view.setScaleY(value);
view.setAlpha(value);
view.setPivotX(0);
view.setPivotY(0);
}
});
valueAnimator.start();