android+动画队列,Android属性动画详解
前言
屬性動畫是Android 3.0(API 11)新加入的動畫框架,屬性動畫彌補了視圖動畫的很多短板,因此已經(jīng)成為大多數(shù)動畫場景的首選框架。
目錄
目錄
1. 屬性動畫出現(xiàn)的原因
在屬性動畫出現(xiàn)以前,Android主要有兩種動畫,幀動畫(Frame Animation)和補間動畫(Tween Animation),這兩種動畫統(tǒng)稱為視圖動畫。幀動畫是通過逐幀播放圖片來實現(xiàn)動畫效果,補間動畫雖然提供了旋轉(zhuǎn)、縮放、位移、透明度的動畫效果,卻有不可忽視的3大缺陷:
作用對象有限,只能作用于View及其子類
動畫種類有限,只有旋轉(zhuǎn)、縮放、位移、透明度4種動畫
只是改變了View的顯示效果,沒有真正改變View的屬性。例如:對
View作位移的補間動畫后,View雖然顯示改變,但是響應(yīng)區(qū)域卻還在原來的位置,這在很多應(yīng)用場景下是不可行的。
因此,為了彌補視圖動畫的不足,屬性動畫就應(yīng)運而生了。
2. 屬性動畫概述
2.1 原理
屬性動畫通過在預(yù)設(shè)的規(guī)則下不斷地改變值,并將值設(shè)置給作用對象的屬性,從而達到動畫效果。這個規(guī)則可以由我們定制,其中有兩個重要的工具,可以幫助我們定制值的變化規(guī)則,一個是插值器(Interpolator),一個是估值器(TypeEvaluator)
2.2 插值器
插值器定義了動畫的變化率,能幫助我們實現(xiàn)非線性改變的動畫。Android提供了幾種插值器,如加速變化的AccelerateInterpolator,先加速后減速的AccelerateDecelerateInterpolator等等,感興趣的朋友可以自行百度查看。如果系統(tǒng)提供的插值器不能滿足我們的要求,我們還可以自定義插值器(通過下面的方式)
/**
* 自定義插值器
* 實現(xiàn)TimeInterpolator接口
*
*/
class MyInterpolator implements TimeInterpolator{
//實現(xiàn)getInterpolation方法
//此方法的參數(shù)input可理解為動畫的進度,值的區(qū)間是在[0,1],在此區(qū)間里隨著時間均勻地改變
//返回值是內(nèi)插值,從廣義上理解是一個時間因子,體現(xiàn)了動畫在時間上的變化因素;從狹義上可理解為動畫改變的百分比
@Override
public float getInterpolation(float input) {
return 0;
}
}
2.3 估值器
估值器的作用是根據(jù)開始值、結(jié)束值、開始結(jié)束之間的一個比例來計算出最終的值。在屬性動畫上則是計算出動畫對應(yīng)的最終的屬性值。系統(tǒng)默認(rèn)提供了3種估值器
IntEvaluator整型估值器,值的類型為整型
FloatEvaluator浮點型估值器,值的類型為浮點型
ArgbEvaluator,值的類型為ARGB值,可以用來計算顏色值
如果系統(tǒng)提供的估值器不能滿足我們的要求,我們還可以自定義估值器
/**
* 自定義估值器
* 實現(xiàn)TypeEvaluator接口
*/
class MyEvaluator implements TypeEvaluator{
/**
*
* @param fraction 開始過渡到結(jié)束之間的一個比例
* @param startValue 開始值
* @param endValue 結(jié)束值
* @return 開始過渡到結(jié)束的具體值
*/
@Override
public T evaluate(float fraction, T startValue, T endValue) {
return null;
}
}
3. 屬性動畫的使用
屬性動畫主要通過兩個類來使用,ValueAnimator和ObjectAnimator,這兩個的區(qū)別主要是ValueAnimator只是計算值,賦值給對象屬性需要我們手動監(jiān)聽值的變化來進行;ObjectAnimator則對賦值屬性這一步封裝進了內(nèi)部,也就是自動賦值。
3.1 ValueAnimator
3.1.1 創(chuàng)建ValueAnimator
創(chuàng)建ValueAnimator可以在代碼里面創(chuàng)建、設(shè)置,也可以在xml里面創(chuàng)建、設(shè)置
xml創(chuàng)建
在res目錄里創(chuàng)建animator目錄,之后創(chuàng)建Animator resources file,ValueAnimator在xml文件的根結(jié)點是animator,例如:
android:valueFrom="30"
android:valueTo="60"
android:duration="2000"
android:valueType="intType" //選擇值的類型
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:repeatMode="reverse"
android:repeatCount="1">
之后直接在代碼里面加載剛才的資源文件就可以了
ValueAnimator valueAnimator= (ValueAnimator) AnimatorInflater.loadAnimator(this,R.animator.textsize_animator);
代碼里創(chuàng)建
雖然ValueAnimator提供了公共的無參的構(gòu)造方法,但是官方建議我們使用其工廠方法來創(chuàng)建ValueAnimator
(1)ValueAnimator.ofInt(int... values)
使用這種方式創(chuàng)建ValueAnimator,值的類型是int,會默認(rèn)使用整形估值器。
(2)ValueAnimator.ofFloat(float... values)
對應(yīng)值的類型是float,會默認(rèn)使用浮點型估值器
(3)ValueAnimator.ofArgb(int... values)
對應(yīng)值的類型是代表顏色的32位的int,會默認(rèn)使用ArgbEvaluator估值器
(4)ValueAnimator.ofObject(TypeEvaluator evaluator,Object... values)
對應(yīng)值的類型是Object,這種方式需要顯式傳入估值器,因為對于Object類型沒有系統(tǒng)提供的估值器,也不可能提供估值器,因為對于不同的對象其計算方式不同
3.1.2 設(shè)置ValueAnimator
ValueAnimator提供了方法設(shè)置其動畫的相關(guān)的屬性,具體如下
valueAnimator.setDuration(2000);//設(shè)置動畫持續(xù)時間,以毫秒為單位
valueAnimator.setInterpolator(new DecelerateInterpolator());//設(shè)置插值器
valueAnimator.setRepeatMode(ValueAnimator.REVERSE);//設(shè)置動畫重復(fù)模式,RESTART表示動畫正序重復(fù),REVERSE代表倒序重復(fù)
valueAnimator.setRepeatCount(1);//設(shè)置重復(fù)次數(shù),也就是動畫播放次數(shù)=RepeatCount+1,ValueAnimator.INFINITE表示無限重復(fù)
valueAnimator.setStartDelay(1000);//設(shè)置動畫延遲播放的時間
3.1.3 監(jiān)聽動畫值
ValueAnimator提供了回調(diào)以監(jiān)聽動畫值,我們可以在此回調(diào)中拿到屬性值并手動賦值給對象屬性,從而達到效果,需要注意的是,對象是View的時候,有時需要我們在賦值屬性后調(diào)用View.invalidate()或者View.requestLayout()方法來刷新界面實現(xiàn)視覺效果
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {//動畫值更新時的監(jiān)聽器
@Override
public void onAnimationUpdate(ValueAnimator animation) {//動畫更新時會回調(diào)此方法
Float value= (Float) animation.getAnimatedValue();//拿到更新后動畫值
tvAnimator.setTextSize(value);//手動將動畫值賦值給對象
}
});
3.2 ObjectAnimator
ObjectAnimator利用反射調(diào)用對象屬性的set方法從而自動賦值給對象屬性完成動畫,也就是說ObjectAnimator作用的對象必須提供該屬性的set方法(如果沒有提供初始值,還必須提供get方法)需要注意的是,set和get方法名必須滿足如下規(guī)則
set/get+屬性名(屬性名頭字母大寫)
3.2.1 創(chuàng)建ObjectAnimator
xml創(chuàng)建
在res/animator目錄下創(chuàng)建animator的xml文件,根結(jié)點為objectAnimator
android:valueType="floatType"
android:valueTo="200.0"
android:valueFrom="100.0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:propertyName="width"
/>
在代碼里加載xml創(chuàng)建的ObjectAnimator并設(shè)置作用對象
ObjectAnimator objectAnimator= (ObjectAnimator) AnimatorInflater.loadAnimator(this,R.animator.test);//加載xml中的動畫
objectAnimator.setTarget(tvAnimator);//設(shè)置作用對象
代碼里創(chuàng)建
和ValueAnimator的方式差不多,這里以ofInt為例說明創(chuàng)建方式,其他的可以類推。
/*
1. 參數(shù)解釋
target:ObjectAnimator作用的對象
propertyName:屬性名
values:過渡值(開始值、結(jié)束值)
*/
ObjectAnimator objectAnimator=ObjectAnimator.ofInt(Object target,String propertyName,int... values);
3.2.2 設(shè)置ObjectAnimator
同ValueAnimator設(shè)置方式一樣,不再贅述。
3.3 AnimatorSet(組合動畫)
AnimatorSet用于把很多動畫按照一定順序組合起來播放,AnimatorSet采用了構(gòu)造器模式來組合動畫
public Builder play(Animator anim) {
if (anim != null) {
return new Builder(anim);
}
return null;
}
//play函數(shù)會生成構(gòu)造器并將該動畫加入到播放隊列中
play函數(shù)是AnimatorSet中唯一可以創(chuàng)建構(gòu)造器的函數(shù),此外構(gòu)造器還提供了多種方法組合動畫,這些方法都是以play函數(shù)傳入的Animator作為基準(zhǔn)來構(gòu)建播放順序的,例如:
//將animator1和animator2一起播放
animatorSet.play(animator1).with(animator2);
//將animator1插入animator2之后播放
animatorSet.play(animator1).after(animator2);
//將animator1插入animator2之前播放
animatorSet.play(animator1).before(animator2);
AnimatorSet本身還提供了兩個方法來添加動畫,
public void playSequentially(Animator... items)//一個接一個地先后播放動畫組,前面的動畫先播放
public void playTogether(Animator... items)//同時播放動畫組
這兩個方法本質(zhì)上也是采用了構(gòu)造器的after、before和with方法來構(gòu)建動畫的播放順序。
3.4 監(jiān)聽動畫
Animator類允許對動畫開始、結(jié)束、取消、重復(fù)和暫停等時刻進行監(jiān)聽
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animator.addPauseListener(new Animator.AnimatorPauseListener() {
@Override
public void onAnimationPause(Animator animation) {
}
@Override
public void onAnimationResume(Animator animation) {
}
});
如果只想監(jiān)聽其中的幾個方法,可以采用AnimatorListenerAdapter
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
}
});
animator.addPauseListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationPause(Animator animation) {
}
});
參考和擴展
總結(jié)
以上是生活随笔為你收集整理的android+动画队列,Android属性动画详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux下apk包名查看,使用adb命
- 下一篇: android软件更新模块实现的技术和方