一、View動(dòng)畫
Android動(dòng)畫分為三種:View動(dòng)畫玻侥、幀動(dòng)畫和屬性動(dòng)畫决摧。
1、View動(dòng)畫的種類
View動(dòng)畫的作用對象是View,支持四種動(dòng)畫效果:平移掌桩、縮放边锁、旋轉(zhuǎn)和透明。上述四種變換效果對應(yīng)著Animation四個(gè)子類: TranslateAnimation 拘鞋、 ScaleAnimation 砚蓬、 RotateAnimation和AlphaAnimation。這四種動(dòng)畫皆可以通過XML定義盆色,也可以通過代碼來動(dòng)態(tài)創(chuàng)建灰蛙。建議采用
xml定義動(dòng)畫,具有更好的可讀性隔躲。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
//動(dòng)畫插值器摩梧,影響動(dòng)畫的播放速度
android:interpolator="@android:anim/accelerate_interpolator"
//表示集合中的動(dòng)畫是否和集合共享一個(gè)插值器
android:shareInterpolator="true"
//表示動(dòng)畫結(jié)束以后,View停留在結(jié)束動(dòng)畫的位置宣旱,如果為false仅父,View會(huì)回到動(dòng)畫開始的位置
android:fillAfter="true" >
//透明度動(dòng)畫,對應(yīng) AlphaAnimation 類浑吟,可以改變 View 的透明度
<alpha
android:duration="3000"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
//旋轉(zhuǎn)動(dòng)畫笙纤,對應(yīng)著 RotateAnimation ,它可以使 View 具有旋轉(zhuǎn)的動(dòng)畫效果
<rotate
android:duration="2000"
android:fromDegrees="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="3000"
android:toDegrees="180" />
<!--通過設(shè)置第一個(gè)alpha動(dòng)畫播放3s后啟動(dòng)rotate動(dòng)畫實(shí)現(xiàn)組合動(dòng)畫,如果不設(shè)置startOffset則同時(shí)播放组力。
pivotX:表示旋轉(zhuǎn)時(shí)候的相對軸的坐標(biāo)點(diǎn)省容,即圍繞哪一點(diǎn)進(jìn)行旋轉(zhuǎn),默認(rèn)情況下軸點(diǎn)是 View 中心
-->
//平移動(dòng)畫燎字,對應(yīng) TranslateAnimation 類腥椒,可以使 View 完成垂直或者水平方向的移動(dòng)效果。
<translate
android:fromXDelta="500"
android:toXDelta="0" />
//縮放動(dòng)畫候衍,對應(yīng) ScaleAnimation 類笼蛛,可以使 View 具有放大和縮小的動(dòng)畫效果。
<scale
android:duration="1000"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50"
android:pivotY="50"
android:toXScale="2"
android:toYScale="2" />
</set>
標(biāo)簽表示動(dòng)畫集合蛉鹿,對應(yīng)AnimationSet類滨砍,可以包含一個(gè)或若干個(gè)動(dòng)畫,內(nèi)部還可以嵌套其他動(dòng)畫集合妖异。
android:fillAfter屬性表示動(dòng)畫結(jié)束以后惨好,View是否停留在結(jié)束動(dòng)畫的位置,如果為 false 随闺, View 會(huì)回到動(dòng)畫開始的位置。這個(gè)參數(shù)在動(dòng)畫 XML 文件的 </set> 節(jié)點(diǎn)中設(shè)置或在程序 Java 代碼中進(jìn)行設(shè)置:setFillAfter(true)蔓腐。
定義完View動(dòng)畫的xml后矩乐,通過以下代碼應(yīng)用動(dòng)畫:
Aniamation anim = AnimationUtils.loadAnimation(context,R.anim.animation_test);
view.startAnimation(anim);
代碼動(dòng)態(tài)創(chuàng)建動(dòng)畫
AlphaAnimation alphaAnimation = new AlphaAnimation(0,1);
alphaAnimation.setDuration(1500);
view.startAnimation(alphaAnimation);
通過setAnimationListener給View動(dòng)畫添加過程監(jiān)聽
public static interface AnimationListener {
void onAnimationStart(Animation animation);
void onAnimationEnd(Animation animation);
void onAnimationRepeat(Animation animation);
}
2、自定義View動(dòng)畫
除了系統(tǒng)提供的四種動(dòng)畫外,我們可以根據(jù)需求自定義動(dòng)畫散罕,自定義一個(gè)新的動(dòng)畫只需要繼 Animation 這個(gè)抽象類分歇,然后重寫它的inatialize
和applyTransformation
這兩個(gè)方法,在initialize 方法中做一些初始化工作欧漱,在applyTransformation方法中進(jìn)行矩陣變換即可职抡,很多時(shí)候采用Camera 來簡化矩陣的變換過程。其實(shí)自定義動(dòng)畫的主要過程就是矩陣變換的過程误甚,矩陣變換是數(shù)學(xué)上的概念缚甩,需要掌握該方面知識(shí)方能輕松實(shí)現(xiàn)自定義動(dòng)畫。
3窑邦、幀動(dòng)畫
幀動(dòng)畫是順序播放一組預(yù)先定義好的圖片擅威,使用簡單,但容易引起OOM冈钦,所以在使用幀動(dòng)畫時(shí)應(yīng)盡量避免使用過多尺寸較大的圖片郊丛。系統(tǒng)提供了另一個(gè)類AnimationDrawble來使用幀動(dòng)畫,使用的時(shí)候瞧筛,需要通過XML定義一個(gè)AnimationDrawble厉熟,如下:
//\res\drawable\frame_animation_list.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">//oneshot 代表著是否只展示一遍
<item
android:drawable="@drawable/one"
android:duration="2000"/>
<item
android:drawable="@drawable/two"
android:duration="2000"/>
<item
android:drawable="@drawable/three"
android:duration="2000"/>
</animation-list>
然后將上述Drawable作為View的背景并播放即可
view.setBackgroundResource(R.drawable.frame_animation_list);
AnimationDrawble drawable = (AnimationDrawble)view.getBackground();
drawable.start();
二、View動(dòng)畫的特殊使用場景
View動(dòng)畫除了可以實(shí)現(xiàn)的四種基本的動(dòng)畫效果外较幌,還可以在一些特殊的場景下使用揍瑟,比如在 ViewGroup 中可以控制子元素的出場效果,在Activity中可以實(shí)現(xiàn)不同Activity之間的切換效果绅络。
1月培、LayoutAnimation
作用于ViewGroup,為ViewGroup指定一個(gè)動(dòng)畫恩急,當(dāng)它的子元素出場時(shí)都會(huì)具有這種動(dòng)畫效
果杉畜,一般用在ListView上。
1.1衷恭、一般步驟
- 定義一個(gè)LayoutAnimation
//res/anim/layout_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="0.5"
android:animationOrder="normal"
android:animation="@anim/zoom_in">
</layoutAnimation>
android:delay
表示子元素開始動(dòng)畫的延時(shí)時(shí)間此叠,取值為子元素入場動(dòng)畫時(shí)間duration的倍數(shù),比如子元素入場動(dòng)畫時(shí)間周期為 300ms 随珠,那么 0.5 表示每個(gè)子元素都需要延遲 150ms 才能播放入場動(dòng)畫灭袁,即第一個(gè)子元素延遲 150ms 開始播放入場動(dòng)畫,第二個(gè)子元素延遲 300ms 開始播放入場動(dòng)畫窗看,依次類推進(jìn)行茸歧。
android:animationOrder
表示子元素動(dòng)畫的開場順序,normal(正序)显沈、reverse(倒序)软瞎、random(隨機(jī))逢唤。
android:animation
為子元素指定具體的入場動(dòng)畫
- 為 ViewGroup 指定屬性
android:layoutAnimation="@anim/layout_animation"
除了xml中指定LayoutAnimation外,也可以通過LayoutAnimationController來實(shí)現(xiàn)
1.2涤浇、LayoutAnimationController是實(shí)現(xiàn)
//用于控制子 view 動(dòng)畫效果
LayoutAnimationController layoutAnimationController= new LayoutAnimationController(AnimationUtils
.loadAnimation(this,R.anim.zoom_in));
layoutAnimationController.setOrder(LayoutAnimationController.ORDER_NORMAL);
listView.setLayoutAnimation(layoutAnimationController);
listView.startLayoutAnimation();
2鳖藕、Activity的切換效果
自定義Activity的切換效果,主要通過overridePendingTransition(int enterAnim, int exitAnim)
方法只锭,enterAnim表示Activity被打開時(shí)候所需的動(dòng)畫資源ID著恩,exitAnim是Activity被暫停時(shí)所需的動(dòng)畫資源ID民逼。該方法必須要在startActivity(intent)和finish()方法之后調(diào)用才會(huì)有效呼巴。
//啟動(dòng)新的Activity帶動(dòng)畫
Intent intent=new Intent(MainActivity.this,Main2Activity.class);
startActivity(intent);
overridePendingTransition(R.anim.zoom_in,R.anim.zoom_out);
//退出Activity本身帶動(dòng)畫
@Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.zoom_in,R.anim.zoom_out);
}
Fragment也可以添加切換動(dòng)畫,通過 FragmentTransation 中的setCustomAnimations()
方法來實(shí)現(xiàn)切換動(dòng)畫羔挡,這個(gè)動(dòng)畫需要的是 View 動(dòng)畫铺呵,不能使用屬性動(dòng)畫裹驰,因?yàn)閷傩詣?dòng)畫也是 API11 才引入的,不兼容片挂。
三幻林、屬性動(dòng)畫
屬性動(dòng)畫是 API 11 引入的新特性,屬性動(dòng)畫可以對任何對象做動(dòng)畫音念,甚至還可以沒有對象沪饺。可以在一個(gè)時(shí)間間隔內(nèi)完成對象從一個(gè)屬性值到另一個(gè)屬性值的改變闷愤。與View動(dòng)畫相比整葡,屬性動(dòng)畫幾乎無所不能,只要對象有這個(gè)屬性讥脐,它都能實(shí)現(xiàn)動(dòng)畫效果遭居。API11以下可以通過nineoldandroids庫來兼容以前版本。
1旬渠、使用屬性動(dòng)畫
屬性動(dòng)畫有ValueAnimator俱萍、ObjectAnimator和AnimatorSet等概念。其中ObjectAnimator繼承自ValueAnimator告丢,AnimatorSet是動(dòng)畫集合枪蘑。
改變一個(gè)對象 TranslationY 屬性,讓其沿著 Y 軸平移一段距離
private void translateViewByObjectAnimator(View targetView){
//TranslationY 目標(biāo) View 要改變的屬性
//ivShow.getHeight() 要移動(dòng)的距離
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(targetView,"TranslationY",ivShow.getHeight());
objectAnimator.start();
}
改變一個(gè)對象的背景色屬性岖免,3秒內(nèi)從0xFFFF8080到0xFF8080FF漸變岳颇,無限循環(huán)且有反轉(zhuǎn)效果
private void changeViewBackGroundColor(View targetView){
ValueAnimator valueAnimator=ObjectAnimator.ofInt(targetView,"backgroundColor", Color.RED,Color.BLUE);
valueAnimator.setDuration(3000);
//設(shè)置估值器,該處插入顏色估值器
valueAnimator.setEvaluator(new ArgbEvaluator());
//無限循環(huán)
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
//反轉(zhuǎn)模式
valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
valueAnimator.start();
}
動(dòng)畫集合颅湘,5 秒內(nèi)對 View 旋轉(zhuǎn)话侧、平移、縮放和透明度進(jìn)行了改變
private void startAnimationSet(View targetView){
AnimatorSet animatorSet=new AnimatorSet();
animatorSet.playTogether(ObjectAnimator.ofFloat(targetView,"rotationX",0,360),
//旋轉(zhuǎn)
ObjectAnimator.ofFloat(targetView,"rotationY",0,360),
ObjectAnimator.ofFloat(targetView,"rotation",0,-90),
//平移
ObjectAnimator.ofFloat(targetView,"translationX",0,90),
ObjectAnimator.ofFloat(targetView,"translationY",0,90),
//縮放
ObjectAnimator.ofFloat(targetView,"scaleX",1,1.5f),
ObjectAnimator.ofFloat(targetView,"scaleY",1,1.5f),
//透明度
ObjectAnimator.ofFloat(targetView,"alpha",1,0.25f,1));
animatorSet.setDuration(3000).start();
}
也可以通過在xml中定義在 res/animator/ 目錄下闯参。具體如下:
\res\animator\value_animator.xml
<?xml version="1.0" encoding="utf-8"?><!--set 標(biāo)簽對應(yīng)著 AnimatorSet-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<!--對應(yīng)著 ObjectAnimator-->
<objectAnimator
android:propertyName="x"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:startOffset="10"
android:valueTo="300"
android:valueType="floatType" />
<!--其中propertyName 屬性設(shè)置為translationX 瞻鹏,valueType 設(shè)置為floatType 可以正常啟動(dòng)
如果 valueType 設(shè)置為 intType 將報(bào)錯(cuò),即屬性類型必須為 floatType 類型术羔,并且android:propertyName="translationX" 表示移動(dòng) 300 ,而 android:propertyName="x"表示移動(dòng)到300 乙漓,是兩個(gè)不同屬性-->
<!--startOffset 指定延遲多久開始播放動(dòng)畫-->
<!--valueType 表示指定的 android:propertyName 所指定屬性的類型,intType 表示指定屬性是整型的释移,
如果指定屬性為顏色叭披,那么不需要指定 valueType 屬性,系統(tǒng)會(huì)自動(dòng)處理
repeatCount 表示動(dòng)畫循環(huán)次數(shù)玩讳,默認(rèn)值為0涩蜘,-1 表示無限循環(huán)-->
<!--對應(yīng)著 ValueAnimator-->
<animator
android:duration="300"
android:valueFrom="0"
android:valueTo="360"
android:startOffset="10"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:valueType="intType"/>
</set>
使用動(dòng)畫
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(context , R.animator.anim);
set.setTarget(view);
set.start();
實(shí)際開發(fā)中建議使用代碼實(shí)現(xiàn)屬性動(dòng)畫。很多時(shí)候一個(gè)屬性的起始值是無法提前確定的熏纯。
2同诫、理解插值器和估值器
時(shí)間插值器( TimeInterpolator)
根據(jù)時(shí)間流逝的百分比來計(jì)算出當(dāng)前屬性值改變的百分比,系統(tǒng)預(yù)置的有LinearInterpolator( 線性插值器:勻速動(dòng)畫) 樟澜,AccelerateDecelerateInterpolator( 加速減速插值器:動(dòng)畫兩頭慢中間快) 误窖,DecelerateInterpolator(減速插值器:動(dòng)畫越來越慢)。
估值器(類型估值算法秩贰, TypeEvaluator)
根據(jù)當(dāng)前屬性改變的百分比來計(jì)算改變后的屬性值霹俺。系統(tǒng)預(yù)置有IntEvaluator(針對整型屬性) 、FloatEvaluator(浮點(diǎn)型屬性) 毒费、ArgbEvaluator(針對 Color 屬性)丙唧。
如圖所示,表示一個(gè)勻速動(dòng)畫觅玻,采用了線性插值器和整型估值算法想际,在 40ms 內(nèi),View 的 X 屬性實(shí)現(xiàn)了從 0 到 40 的變化溪厘。
屬性動(dòng)畫要求對象的該屬性有 set 和 get(可選) 方法胡本,插值器和估值算法除了系統(tǒng)提供的外,我們還可以自己定義桩匪,插值器或者估值算法都是一個(gè)接口打瘪,且內(nèi)部只有一個(gè)方法,我們只需要派生一個(gè)類實(shí)現(xiàn)該接口即可傻昙,然后就可以做出千變?nèi)f化的動(dòng)畫效果了闺骚。具體而言是:自定義插值器需要實(shí)現(xiàn) Interpolator 或者 TimeInterpolator ,自定義估值算法需要實(shí)現(xiàn) TypeEvaluator 妆档。如果要對其他類型(非int,float,color)做動(dòng)畫僻爽,必須要自定義類型估值算法。
3贾惦、屬性動(dòng)畫的監(jiān)聽器
屬性動(dòng)畫提供了監(jiān)聽器用于監(jiān)聽動(dòng)畫的播放過程胸梆,主要有如下兩個(gè)接口:AnimatorUpdateListener 和 AnimatorListener 敦捧。
public static interface AnimatorListener {
void onAnimationStart(Animator animation); //動(dòng)畫開始
void onAnimationEnd(Animator animation); //動(dòng)畫結(jié)束
void onAnimationCancel(Animator animation); //動(dòng)畫取消
void onAnimationRepeat(Animator animation); //動(dòng)畫重復(fù)播放
}
為了方便開發(fā),系統(tǒng)提供了AnimatorListenerAdapter類碰镜,它是AnimatorListener的適配器類兢卵,可以有選擇的實(shí)現(xiàn)以上4個(gè)方法。
public static interface AnimatorUpdateListener {
void onAnimationUpdate(ValueAnimator animation);
}
AnimatorUpdateListener會(huì)監(jiān)聽整個(gè)動(dòng)畫的過程绪颖,動(dòng)畫由許多幀組成的秽荤,每播放一幀,onAnimationUpdate就會(huì)調(diào)用一次柠横。利用這個(gè)特性窃款,我們可以做一些特殊的事情。
4牍氛、對任意屬性做動(dòng)畫
屬性動(dòng)畫原理:屬性動(dòng)畫要求動(dòng)畫作用的對象提供 get 方法和 set 方法晨继,屬性動(dòng)畫根據(jù)外界傳遞該屬性的初始值和最終值以動(dòng)畫的效果去多次調(diào)用 set 方法,每次傳遞給 set 方法的值都不一樣搬俊,確切的來說是隨著時(shí)間的推移紊扬,所傳遞的值越來越接近最終值∮颇ǎ總結(jié)一下珠月,我們對 object 對象屬性 abc 做動(dòng)畫,如果想要?jiǎng)赢嬌ǖ校瑫r(shí)滿足兩個(gè)條件:
- object 必須要提供 setAbc() 方法啤挎,如果動(dòng)畫的時(shí)候沒有傳遞初始值,那么還要提供 getAbc() 方法卵凑,因?yàn)橄到y(tǒng)要去取 abc 屬性的初始值(如果這條不滿足庆聘,程序直接crash)。
- object 的 setAbc() 對屬性 abc 所做的改變必須能夠通過某種方法反應(yīng)出來(即最終體現(xiàn)了 UI 的變化)勺卢,比如會(huì)帶來 UI 的改變之類(如果這條不滿足伙判,動(dòng)畫無效果,但是程序不會(huì)crash)黑忱。
我們給 Button 的 width 屬性做動(dòng)畫無效果但是沒有crash的原因就是 Button 內(nèi)部提供了 setWidth 和 getWidth 方法宴抚,但是這個(gè) setWidth 方法并不是改變 UI 大小的,而是用來設(shè)置最大寬度和最小寬度的甫煞。對于上面屬性動(dòng)畫的兩個(gè)條件來說菇曲,這個(gè)例子只滿足了條件 1 而未滿足條件 2。
針對上面問題抚吠,官方文檔給出了 3 種解決方法:
- 請給你的對象加上get和set方法常潮,如果你有權(quán)限的話
對于SDK或者其他第三方類庫的類無法加上的 - 用一個(gè)類來包裝原始對象,間接為其提供get和set方法
/**
* 將 Button 沿著 X 軸方向放大
* @param button
*/
private void performAnimationByWrapper(View button){
ViewWrapper viewWrapper=new ViewWrapper(button);
ObjectAnimator.ofInt(viewWrapper,"width",800)
.setDuration(5000)
.start();
}
private class ViewWrapper {
private View targetView;
public ViewWrapper(View targetView) {
this.targetView = targetView;
}
public int getWidth() {
//注意調(diào)用此函數(shù)能得到 View 的寬度的前提是楷力, View 的寬度是精準(zhǔn)測量模式喊式,即不可以是 wrap_content
//否則得不到正確的測量值
return targetView.getLayoutParams().width;
}
public void setWidth(int width) {
//重寫設(shè)置目標(biāo) view 的布局參數(shù)孵户,使其改變大小
targetView.getLayoutParams().width = width;
//view 大小改變需要調(diào)用重新布局
targetView.requestLayout();
}
}
- 采用ValueAnimator,監(jiān)聽動(dòng)畫過程岔留,自己實(shí)現(xiàn)屬性的改變
ValueAnimator 本身不作用于任何對象夏哭,也就是說直接使用它沒有任何動(dòng)畫效果(所以系統(tǒng)提供了它的子類 ObjectAnimator 供我們直接使用,作用于對象直接執(zhí)行動(dòng)畫效果献联,而 ValueAnimator 只是提供改變一個(gè)值的過程方庭,并能監(jiān)聽到整個(gè)值的改變過程,我們基于這個(gè)過程可以自己去實(shí)現(xiàn)動(dòng)畫效果酱固,在這個(gè)過程中做想要達(dá)到的效果,自己去實(shí)現(xiàn))头朱。它可以對一個(gè)值做動(dòng)畫运悲,然后我們可以監(jiān)聽其動(dòng)畫過程,在動(dòng)畫過程中修改我們對象的屬性项钮,這樣我們自己就實(shí)現(xiàn)了對對象做了動(dòng)畫班眯。
//new 一個(gè)整型估值器,用于下面比例值計(jì)算使用(可以自己去計(jì)算烁巫,這里直接使用系統(tǒng)的)
private IntEvaluator intEvaluator = new IntEvaluator();
private void performAnimatorByValue(final View targetView, final int start, final int end) {
ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//獲取當(dāng)前動(dòng)畫進(jìn)度值
int currentValue = (int) animation.getAnimatedValue();
//獲取當(dāng)前進(jìn)度占整個(gè)動(dòng)畫比例
int fraction = (int) animation.getAnimatedFraction();
//直接通過估值器根據(jù)當(dāng)前比例計(jì)算當(dāng)前 View 的寬度,然后設(shè)置給 View
targetView.getLayoutParams().width = intEvaluator.evaluate(fraction, start, end);
targetView.requestLayout();
}
});
valueAnimator.setDuration(5000)
.start();
}
5署隘、屬性動(dòng)畫的工作原理
屬性動(dòng)畫需要運(yùn)行在有Looper的線程中,系統(tǒng)通過反射調(diào)用被作用對象get/set方法亚隙。
四磁餐、使用動(dòng)畫的注意事項(xiàng)
- OOM問題
使用幀動(dòng)畫時(shí),當(dāng)圖片數(shù)量較多且圖片分辨率較大的時(shí)候容易出現(xiàn)OOM阿弃,需注意诊霹,盡量避免使用幀動(dòng)畫。 - 內(nèi)存泄漏
使用無限循環(huán)的屬性動(dòng)畫時(shí)渣淳,在Activity退出時(shí)即使停止脾还,否則將導(dǎo)致Activity無法釋放從而造成內(nèi)存泄露。 - 兼容性問題
動(dòng)畫在3.0以下的系統(tǒng)存在兼容性問題入愧,特殊場景可能無法正常工作鄙漏,需做好適配工作。 - View動(dòng)畫的問題
View動(dòng)畫是對View的影像做動(dòng)畫棺蛛,并不是真正的改變了View的狀態(tài)怔蚌,因此有時(shí)候會(huì)出現(xiàn)動(dòng)畫完成后View無法隱藏( setVisibility(View.GONE) 失效) ,這時(shí)候調(diào)用 view.clearAnimation() 清理View動(dòng)畫即可解決鞠值。 - 不要使用px
使用px會(huì)導(dǎo)致不同設(shè)備上有不同的效果媚创。 - 動(dòng)畫元素的交互
View動(dòng)畫是對View的影像做動(dòng)畫,View的真實(shí)位置沒有變動(dòng)彤恶,動(dòng)畫完成后的新位置是無法觸發(fā)點(diǎn)擊事件的钞钙。屬性動(dòng)畫是真實(shí)改變了View的屬性鳄橘,所以動(dòng)畫完成后的位置可以接受觸摸事件。 - 硬件加速
使用動(dòng)畫的過程中芒炼,使用硬件加速可以提高動(dòng)畫的流暢度瘫怜。