當前位置:首頁 » 安卓系統 » android動畫實例

android動畫實例

發布時間: 2023-03-24 05:32:35

A. Android開發之ImageView播放GIF動畫實例

Android開發之ImageView播放GIF動畫實例

Android的原生控制項並不支持播放GIF格式的圖片,如果想在Android中顯示一張GIF動態圖片,可以利用 ImageView控制項來完成,但是放進去之後,你會發現,ImageView它只會顯示這張圖片的第一幀,不會產生任何的動畫效果。我們必須通過自定義控制項的方式來實現ImageView播放GIF 圖片的功能。

首先我們來編寫一個PowerImageView控制項,讓它既能支持ImageView控制項原生的所有功能,同時還可以播放GIF動態圖片。

先新建一個項目PowerImageViewTest,這里使用Android 4.0+Eclipse。

由於是要自定義控制項,會需要一些自定義的控制項屬性,因此我們需要在values目錄下新建一個attrs.xml的文件,在這個文件中添加項目需要的自定義屬性。

這里我們目前暫時只需要一個自動播放auto_play屬性,XML文件代碼如下:

<?xml version="1.0" encoding="utf-8"?>

這個文件完成之後,下面我們來開始編寫主類PowerImageView類,由於PowerImageView類需要支持ImageView的所有功能,我們必須要讓PowerImageView繼承自ImageView,代碼如下:

public class PowerImageView extends ImageView implements OnClickListener {

/**

* 播放GIF動畫的關鍵類

*/

private Movie mMovie;

/**

* 開始播放按鈕圖片

*/

private Bitmap mStartButton;

/**

* 記錄動畫開始的時間

*/

private long mMovieStart;

/**

* GIF圖片的寬度

*/

private int mImageWidth;

/**

* GIF圖片的高度

*/

private int mImageHeight;

/**

* 圖片是否正在播放

*/

private boolean isPlaying;

/**

* 是否允許自動播放

*/

private boolean isAutoPlay;

/**

* PowerImageView構造函數。

*

* @param context

*/

public PowerImageView(Context context) {

super(context);

}

/**

* PowerImageView構造函數。

*

* @param context

*/

public PowerImageView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

/**

* PowerImageView構造函數,在這里完成所有必要的初始化操作。

*

* @param context

*/

public PowerImageView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PowerImageView);

int resourceId = getResourceId(a, context, attrs);

if (resourceId != 0) {

// 當資源id不等於0時,就去獲取該資源的流

InputStream is = getResources().openRawResource(resourceId);

// 使用Movie類對流進行解碼

mMovie = Movie.decodeStream(is);

if (mMovie != null) {

// 如果返回值不等於null,就說明這是一個GIF圖片,下面獲取是否自動播放的屬性

isAutoPlay = a.getBoolean(R.styleable.PowerImageView_auto_play, false);

Bitmap bitmap = BitmapFactory.decodeStream(is);

mImageWidth = bitmap.getWidth();

mImageHeight = bitmap.getHeight();

bitmap.recycle();

if (!isAutoPlay) {

// 當不允許自動播放的時候,得到開始播放按鈕的圖片,並注冊點擊事件

mStartButton = BitmapFactory.decodeResource(getResources(),R.drawable.start_play);

setOnClickListener(this);

}

}

}

}


@Override

public void onClick(View v) {

if (v.getId() == getId()) {

// 當用戶點擊圖片時,開始播放GIF動畫

isPlaying = true;

invalidate();

}

}


@Override

protected void onDraw(Canvas canvas) {

if (mMovie == null) {

// mMovie等於null,說明是張普通的圖片,則直接調用父類的onDraw()方法

super.onDraw(canvas);

} else {

// mMovie不等於null,說明是張GIF圖片

if (isAutoPlay) {

// 如果允許自動播放,就調用playMovie()方法播放GIF動畫

playMovie(canvas);

invalidate();

} else {

// 不允許自動播放時,判斷當前圖片是否正在播放

if (isPlaying) {

// 正在播放就繼續調用playMovie()方法,一直到動畫播放結束為止

if (playMovie(canvas)) {

isPlaying = false;

}

invalidate();

} else {

// 還沒開始播放就只繪制GIF圖片的第一幀,並繪制一個開始按鈕

mMovie.setTime(0);

mMovie.draw(canvas, 0, 0);

int offsetW = (mImageWidth - mStartButton.getWidth()) / 2;

int offsetH = (mImageHeight - mStartButton.getHeight()) / 2;

canvas.drawBitmap(mStartButton, offsetW, offsetH, null);

}

}

}

}


@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

if (mMovie != null) {

// 如果是GIF圖片則重寫設定PowerImageView的大小

setMeasuredDimension(mImageWidth, mImageHeight);

}

}


/**

* 開始播放GIF動畫,播放完成返回true,未完成返回false。

*

* @param canvas

* @return 播放完成返回true,未完成返回false。

*/

private boolean playMovie(Canvas canvas) {

long now = SystemClock.uptimeMillis();

if (mMovieStart == 0) {

mMovieStart = now;

}

int ration = mMovie.ration();

if (ration == 0) {

ration = 1000;

}

int relTime = (int) ((now - mMovieStart) % ration);

mMovie.setTime(relTime);

mMovie.draw(canvas, 0, 0);

if ((now - mMovieStart) >= ration) {

mMovieStart = 0;

return true;

}

return false;

}


/**

* 通過java反射,獲取到src指定圖片資源所對應的id。

*

* @param a

* @param context

* @param attrs

* @return 返回布局文件中指定圖片資源所對應的id,沒有指定任何圖片資源就返回0。

*/

private int getResourceId(TypedArray a, Context context, AttributeSet attrs) {

try {

Field field = TypedArray.class.getDeclaredField("mValue");

field.setAccessible(true);

TypedValue typedValueObject = (TypedValue) field.get(a);

return typedValueObject.resourceId;

} catch (Exception e) {

e.printStackTrace();

} finally {

if (a != null) {

a.recycle();

}

}

return 0;

}


}

這個類的代碼注釋已經非常詳細了,我再來簡單地解釋一下。可以看到,我們重寫了ImageView中所有的構建函數,使得 PowerImageView的用法可以和ImageView完全相同。在構造函數中,則是對所有必要的數據進行了初始化操作。首先,我們調用了 getResourceId()方法去獲取圖片資源對應的id值,在getResourceId()方法內部是通過Java的反射機制來進行獲取的。得到了圖片資源的id後,我們將它轉換成InputStream,然後傳入到Movie.decodeStream()方法中以解碼出Movie對象。如果得到的Movie對象等於null,說明這是一張普通的圖片資源,就不再進行任何特殊處理,因為父類ImageView都幫我們處理好了。如果得到的 Movie對象不等於null,則說明這是一張GIF圖片,接著就要去獲取是否允許自動播放、圖片的寬高等屬性的值。如果不允許自動播放,還要給播放按鈕 注冊點擊事件,默認是不允許自動播放的。

接下來會進入到onMeasure()方法中。在這個方法中我們進行判斷,如果這是一張GIF圖片,則需要將PowerImageView的寬高重定義,使得控制項的大小剛好可以放得下這張GIF圖片。

再往後就會進入到onDraw()方法中。在這個方法里同樣先判斷當前是一張普通的圖片還是GIF圖片,如果是普通的圖片就直接調用 super.onDraw()方法交給ImageView去處理就好了。如果是GIF圖片,則先判斷該圖是否允許自動播放,允許的話就調用 playMovie()方法去播放GIF圖片就好,不允許的話則會先在PowerImageView中繪制該GIF圖片的第一幀,並在圖片上繪制一個播放 按鈕,當用戶點擊了播放按鈕時,再去調用playMovie()方法去播放GIF圖片。

下面我們來看看playMovie()方法中是怎樣播放GIF圖片的吧。可以看到,首先會對動畫開始的時間做下記錄,然後對動畫持續的時間做下記 錄,接著使用當前的時間減去動畫開始的時間,得到的時間就是此時PowerImageView應該顯示的那一幀,然後藉助Movie對象將這一幀繪制到屏 幕上即可。之後每次調用playMovie()方法都會繪制一幀圖片,連貫起來也就形成了GIF動畫。注意,這個方法是有返回值的,如果當前時間減去動畫 開始時間大於了動畫持續時間,那就說明動畫播放完成了,返回true,否則返回false。

完成了PowerImageView的編寫,下面我們就來看一看如何使用它吧,其實非常簡單,打開或新建activity_main.xml,代碼如下所示:

<relativelayout p=""

android:layout_width="match_parent"

android:layout_height="match_parent" >


<com.example.powerimageviewtest.powerimageview p=""

android:id="@+id/image_view"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:src="@drawable/anim"

/>


可以看到,PowerImageView的用法和ImageView幾乎完全一樣,使用android:src屬性來指定一張圖片即可,這里指定的anim就是一張GIF圖片。然後我們讓PowerImageView在布局裡居中顯示MainActivity中的代碼都是自動生成的,這里就不再貼出來了。在AndroidManifest.xml中還有一點需要注意,有些4.0 以上系統的手機啟動了硬體加速功能之後會導致GIF動畫播放不出來,因此我們需要在AndroidManifest.xml中去禁用硬體加速功能,可以通過指定android:hardwareAccelerated屬性來完成,代碼如下所示:

<?xml version="1.0" encoding="utf-8"?>

<manifest p=""

package="com.example.powerimageviewtest"

android:versionCode="1"

android:versionName="1.0" >


<uses-sdk p=""

android:minSdkVersion="14"

android:targetSdkVersion="17" />


android:allowBackup="true"

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme"

android:hardwareAccelerated="false"

>

android:name="com.example.powerimageviewtest.MainActivity"

android:label="@string/app_name" >


現在可以來運行一下代碼了,一打開程序你就會看到GIF圖片的第一幀,點擊圖片之後就可以播放GIF動畫了。

然後我們還可以通過修改activity_main.xml中的代碼,給它加上允許自動播放的屬性,代碼如下所示:

<relativelayout p=""

xmlns:attr="http://schemas.android.com/apk/res/com.example.powerimageviewtest"

android:layout_width="match_parent"

android:layout_height="match_parent" >


<com.example.powerimageviewtest.powerimageview p=""

android:id="@+id/image_view"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:src="@drawable/anim"

attr:auto_play="true"

/>


這里使用了剛才我們自定義的屬性,通過attr:auto_play來啟用和禁用自動播放功能。現在將auto_play屬性指定成true後,PowerImageView上就不會再顯示一個播放按鈕,而是會循環地自動播放動畫。不僅如此,PowerImageView還繼承了ImageView原生的所有功能,只要指定的不是GIF圖 片,PowerImageView表現的結果就和ImageView完全一致,現在我們來放一張普通的PNG圖片,修改 activity_main.xml中的代碼,如下所示:

<relativelayout p=""

android:layout_width="match_parent"

android:layout_height="match_parent" >


<com.example.powerimageviewtest.powerimageview p=""

android:id="@+id/image_view"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:src="@drawable/myphoto"

/>


這里在src屬性裡面指定了一張名字為myphoto的PNG圖片,圖片在布局正中央顯示出來了,正是普通ImageView所具備的功能。我們還可以在PowerImageView中指定android:scaleType等屬性,用法和原生的ImageView完全一樣。

B. Carson帶你學Android:常見的三種動畫類型

Android 動畫主要分為分為兩大類(三種):

下面。我將簡單介紹這兩大類、三種 Android 常用動畫

根據不同的動畫效果,補間動畫分為4種動畫:

具體效果分別如下:

較為復雜的個性化動畫效果。

將動畫拆分後的圖片幀

在 Android 3.0 ( API 11 )後才提供的一種全新動畫模式

與屬性相關、更加復雜的動畫效果。

不定期分享關於 安卓開發 的干貨,追求 短、平、快 ,但 卻不缺深度

C. Android動畫一:Activity過渡動畫詳細實現原理

雖然 Android 5.0 之後推出了新的過渡動畫方式,但通常只是用於特定的場合使用, activity.overridePendingTransition() 通用方式的過渡動畫還是很常用。

overridePendingTransition有兩個參數,第一個參數(enterAnim)是作用於SecondActivity 的 進入屏幕可見區域 效果,第二個參數(exitAnim)是作用於當前 Activity 離開屏幕可見區域 效果。

iOS 默認的效果,新的Activity從右邊(R)數蘆進入顯示區域,當前Activity從左邊離開顯示區域到(L)。

enterAnim(activity_right_to_left_enter.xml):X軸從 100% 到 0

exitAnim(activity_right_to_left_exit.xml):X軸從 0 到 -100%

使用

一般從底部彈出新Activity,就是從B區域到屏幕可薯悔帶見區域,當前的Activity是保持不變的。
enterAnim(activity_bottom_to_top_enter.xml):Y軸從 100% 到 0

exitAnim(no_anim.xml):Y軸保持不變

使用

前面講了startActivity的轉場動畫,下面講finish()的轉場動畫。overridePendingTransition有兩個參數,第一個參數(enterAnim)是作用於上一個Activity的進入屏幕可見區域效果,第二個參數(exitAnim)是作用於當前嘩前 Activity 離開屏幕可見區域效果。

iOS默認的finish動畫,是當前的Activity從屏幕可見區域到R區域,上一個Activity從L區域到屏幕可見區域。

enterAnim(activity_left_to_right_enter.xml):X軸從 -100% 到 0

exitAnim(activity_left_to_right_exit.xml):X軸從 0 到 100%

使用

從屏幕底部滑出效果是,當前Activity從底部滑出屏幕可見區域,上一個Activity保持不變,和BottomIn不同的是,enterAnim是不需要使用動畫,因為上一個Activity已經在屏幕的後面了,只需要改變當前Activity消失的效果。
exitAnim(activity_top_to_bottom_exit.xml):Y軸從 0 到 100%

使用

https://github.com/taoweiji/ActivityAnimationExample

D. Android 動畫詳解

  android中酷炫的效果,都離不開動畫的支持。這里我們詳細介紹一下android中動畫的分類。android的中動畫分為幀動畫、補間動畫、屬性動畫。原理各不相同,實現的效果也大不相同。下面一一講解三種動畫。

  幀動畫顧名思義就是通過順序一幀一幀播放圖片從而產生動畫效果,效果類似放電影。該動畫缺點比較明顯,就是如果圖片過大過多會導致OOM。幀動畫xml文件放置在drawable目錄下而非anim文件夾下。

  補間動畫是通過對view進行旋轉、縮放、漸變、透明度變化,而達到的一種動畫效果。是一種漸進式動畫。並且可以通過組合以上四種操作,完成復雜的自定義動畫效果。缺點就是只是改變的view的展示狀態,但是不會改變view的位置。例如我們將一個button通過位移想左移動100dp,然後停留在終點。但是我們可以發現展示的位置button點擊無效果,不可以交互。而在button原始位置空白的地方點擊會觸發button的點擊效果。也就是button本質還是在原來位置,只是展示左移了100dp。

透明度動畫,通過改變view的透明度展示動畫。對應AlphaAnimation和<alpha>xml標簽

縮放動畫,通過修改view的大小展示動畫。對應ScaleAnimation類和<scale>xml表情

通過旋轉view展示動畫。對應RotateAnimation類和<rotate>xml標簽

平移動畫,更改view的展示位置展示動畫。對應TranslateAnimation類和<translate>xml表情

應用動畫xml配置

使用java類配置動畫,具體參數類同xml參數,建議使用xml配置動畫

  屬性動畫本質是通過改變對象的屬性(例如:x,y等屬性),來實現動畫的,所以基本上是無所不能的,只要對象有這個屬性,就能實現動畫效果。屬性動畫是在api11的新特性,通過動態的改變view的屬性從而達到動畫效果。雖然可以使用nineoldandroid庫向下兼容,但是兼容本質是使用補間動畫完成,也就是說不會更改view的屬性,也不會更改view的位置。屬性動畫比較常用的類: ValueAnimator、ObjectAnimator、AnimationSet,其中ObjectAnimator是ValueAnimator的子類,而AnminationSet是動畫集合

動畫配置同樣可以使用xml配置,參數類似,這里不做詳細說明。

根據時間流逝百分比計算當前屬性改變百分比。同xml配置動畫中的 android:interpolator 屬性配置,常見有LinearInterpolator(線性差值器)、(加速減速差值器)
等。自定義需要實現 Interpolator 或者 TimeInterpolator 。Interpolator介面繼承TimeInterpolator。

根據當前屬性改變百分比計算改變後的屬性值。屬性動畫特有的屬性。自定義估值器需要實現 TypeEvaluator 介面。

可以對任意屬性做屬性動畫,屬性動畫要求動畫作用的對象提供該屬性的get()和set()方法。因為屬性動畫本質就是根據外界傳遞的對象屬性的初始值和終點值,然後根據估值器和差值器計算屬性值,不斷調用屬性的set方法,通過時間的推移所傳遞的值,越來越近終點值。
注意:

使用ValueAnimator通過監聽動畫過程,自己改變對象屬性完成動畫

E. 【Android 動畫】動畫詳解之補間動畫(一)

之前很早就想寫寫Android 的動畫,最近剛好有時間,大概聊一聊安卓動畫。

個人習慣將動畫分為:補間動畫(透明度、旋轉、位移、縮放)、幀動畫、和屬性動畫,這一篇,我們先說說補間動畫。
補間動畫這個詞出於flash,在兩個關鍵幀( 可以理解成動畫開始和結束 )中間需要做「補間動畫」,才能實現圖畫的運動;插入補間動畫後兩個關鍵幀之間的插補幀是由計算機自動運算而得到的。
實際上,Android 的補間動畫也是由我們指定動畫開始、動畫結束2個關鍵點,中間部分的動畫由系統完成

在正式開始之前,我們先說下Android 系統的坐標系,屏幕左上角為坐標原點,假如屏幕為1080*1980,那麼左上角為(0,0),右上角為(1080,0),左下角為(0,1980),右下角為(1080,1980)

所有動畫有以下公共屬性,注釋比較詳細,這里就不在詳述了

ScaleAnimation有3種構造方法

我們先看第一種,其起始比例為0,縮放比例為1.4,即放大到1.4倍

效果如下:

第二種,pivotx,pivotY分別代表起始位置的x、y方向的坐標,我們設置為(100,100)

效果如下:

第三種,pivotXType和pivotYType有2種模式,RELATIVE_TO_SELF(相對於自身)和RELATIVE_TO_PARENT(相對於父布局),如果設置這個,pivotx,pivotY的值就應該是0-1的浮點數,這里分別對應xml中的%(自身)和%p(父布局)

TranslateAnimation有2種構造方法,和ScaleAnimation類似

效果如下:

效果如下:

RELATIVE_TO_PARENT

效果如下:

RotateAnimation有3種構造方法

順時針720度

效果如下:

逆時針720度

效果如下:

效果如下:

再來RELATIVE_TO_PARENT

效果如下:

這是什麼鬼???怎麼跑到屏幕外面去了?
原來設置為RELATIVE_TO_PARENT時,旋轉中心x方向應該為該空間離左邊的邊距+父布局寬度/2,y方向同理,而此時,我們布局中紅色的Textview為居中狀態,所以旋轉中心為屏幕右下角。讓我們來看個例子
修改布局如下:

效果如下:

這時,我們看到旋轉中心x方向為離左邊100dp處

AlphaAnimation只有1種構造方法

其中fromAlpha為動畫開始的透明度;toAlpha為動畫結束的透明度

效果如下:

效果如下:

AnimationSet是一個動畫的集合,可以按照添加的順序播放動畫,讓我們來看個例子,通過組合動畫,實現旋轉漸入動畫

效果如下:

到這里,補間動畫就介紹完了

參考資料: 自定義控制項三部曲之動畫篇

F. Android播放Spine骨骼動畫筆記

官方實例: http://zh.esotericsoftware.com/spine-demos
官方工具: EsotericSoftware / spine-runtimes
java相關包: https://github.com/EsotericSoftware/spine-runtimes/tree/3.8/spine-libgdx

Libgdx實現和原生view進行層級透明疊加,修改GLSurfaceView為GLTextureview:
https://www.pianshen.com/article/6271275180/
此篇文章CSDN地址

檢查了我們的json文件中的name,沒有為null值的啊,於是對比可以運行的spine文件json發現:

最後發現是果然還是我的libgdx太搭並老,升級為最新的運枝握即旁慶可

之前的版本是

注意:升級成為新版本,那麼格式也要用新版本,就是那種預設了欄位的json格式
所以版本匹配很重要。

而Demo只有 'armeabi','armeabi-v7a', 'x86' 這三個so的支持,於是我們修改配置如下

於是就可以正確的運行了,如果想支持其他的cup架構,那麼就要找到對應的架構的 libgdx.so 文件,添加到項目中。

更新後:

這是1.9.10的介紹: https://www.badlogicgames.com/wordpress/

G. android屬性動畫詳解

在 Android 動畫中,總共有兩種類型的動畫View Animation(視圖動畫)和Property Animator(屬性動畫);其中
View Animation包括Tween Animation(補間動畫)和Frame Animation(逐幀動畫);
Property Animator包括ValueAnimator和ObjectAnimation;
首先,直觀上,他們有如下三點不同:
1、引入時間不同: View Animation是API Level 1就引入的。Property Animation是API Level 11引入的,即Android 3.0才開始有Property Animation相關的API。
2、所在包名不同: View Animation在包android.view.animation中。而Property Animation API在包 android.animation中。
3、動畫類的命名不同: View Animation中動畫類取名都叫XXXXAnimation,而在Property Animator中動畫類的取名則叫XXXXAnimator大家都知道逐幀動畫主要是用來實現動畫的,而補間動畫才能實現控制項的漸入漸出、移動、旋轉和縮放的;而Property Animator是在Android 3.0版本才引入的,之前是沒有的。
為什麼還要引入Property Animator呢?
1、為什麼引入Property Animator(屬性動畫)
我提出一個假設:請問大家,如何利用補間動畫來將一個控制項的背景色在一分鍾內從綠色變為紅色?這個效果想必沒辦法僅僅通過改變控制項的漸入漸出、移動、旋轉和縮放來實現吧,而這個效果是可以通過Property Animator完美實現的
**這就是第一個原因:Property Animator能實現補間動畫無法實現的功能 **大家都知道,補間動畫和逐幀動畫統稱為View Animation,也就是說這兩個動畫只能對派生自View的控制項實例起作用;而Property Animator則不同,從名字中可以看出屬性動畫,應該是作用於控制項屬性的!正因為屬性動畫能夠只針對控制項的某一個屬性來做動畫,所以也就造就了他能單獨改變控制項的某一個屬性的值!比如顏色!這就是Property Animator能實現補間動畫無法實現的功能的最重要原因。
**我們得到了第二點不同:View Animation僅能對指定的控制項做動畫,而Property Animator是通過改變控制項某一屬性值來做動畫的。
**假設我們將一個按鈕從左上角利用補間動畫將其移動到右下角,在移動過程中和移動後,這個按鈕都是不會響應點擊事件的。這是為什麼呢?因為補間動畫僅僅轉變的是控制項的顯示位置而已,並沒有改變控制項本身的值。View Animation的動畫實現是通過其Parent View實現的,在View被drawn時Parents View改變它的繪制參數,這樣雖然View的大小或旋轉角度等改變了,但View的實際屬性沒變,所以有效區域還是應用動畫之前的區域;我們看到的效果僅僅是系統作用在按鈕上的顯示效果,利用動畫把按鈕從原來的位置移到了右下角,但按鈕內部的任何值是沒有變化的,所以按鈕所捕捉的點擊區域仍是原來的點擊區域。(下面會舉例來說明這個問題)
這就得到了第三點不同:補間動畫雖能對控制項做動畫,但並沒有改變控制項內部的屬性值。而Property Animator則是恰恰相反,Property Animator是通過改變控制項內部的屬性值來達到動畫效果的

我們前面講了Property Animator包括ValueAnimator和ObjectAnimator;這篇文章就主要來看看ValueAnimator的使用方法吧。
我覺得谷歌那幫老頭是最會起名字的人,單從命名上,就能看出來這個東東的含義。ValueAnimator從名字可以看出,這個Animation是針對值的! ValueAnimator不會對控制項做任何操作,我們可以給它設定從哪個值運動到哪個值,通過監聽這些值的漸變過程來自己操作控制項。 它會自己計算動畫的過程,然後我們需要監聽它的動畫過程來自己操作控制項。

這就是ValueAnimator的功能:ValueAnimator對指定值區間做動畫運算,我們通過對運算過程做監聽來自己操作控制項。
總而言之就是兩點:
1. ValueAnimator只負責對指定的數字區間進行動畫運算
2. 我們需要對運算過程進行監聽,然後自己對控制項做動畫操作

插值器的意義其實就相當於物理公式中的加速度參數,所以這也就是它也叫加速器的原因。 如何自定義插值器:

**input參數與任何我們設定的值沒關系,只與時間有關,隨著時間的增長,動畫的進度也自然的增加,input參數就代表了當前動畫的進度。而返回值則表示動畫的當前數值進度 **

在getInterpolation函數中,我們將進度反轉過來,當傳0的時候,我們讓它數值進度在完成的位置,當完成的時候,我們讓它在開始的位置

ObjectAnimator是派生自ValueAnimator的,所以ValueAnimator中所能使用的方法,在ObjectAnimator中都可以正常使用。ObjectAnimator重寫了幾個方法,比如ofInt(),ofFloat()等。利用ObjectAnimator重寫的ofFloat方法如何實現一個動畫:(改變透明度)

前面我們都是定義多個值,即至少兩個值之間的變化,那如果我們只定義一個值呢,如下面的方式:(同樣以MyPointView為例)

僅且僅當我們只給動畫設置一個值時,程序才會調用屬性對應的get函數來得到動畫初始值。如果動畫沒有初始值,那麼就會使用系統默認值。比如ofInt()中使用的參數類型是int類型的,而系統的Int值的默認值是0,所以動畫就會從0運動到100;也就是系統雖然在找到不到屬性對應的get函數時,會給出警告,但同時會用系統默認值做為動畫初始值。
如果通過給自定義控制項MyPointView設置了get函數,那麼將會以get函數的返回值做為初始值。

根據 View setBackGroundColor() 方法可以自定義條用屬性動畫。

H. 如何高效學習Android動畫

Android動畫初步
動畫(Animation)在我們日常的Android開發工作當中使用得較為頻繁,尤其對於Android游戲這個動畫的集合體,掌握動畫開發的重要性毋庸置疑。同樣的,在Android應用開發中我們也經常使用動畫效果來提升APP用戶體驗,比如應用中的圖片的旋轉,頁面和頁面之間的淡入淡出、左右漸入漸出切換效果等等。
動畫的分類
Android FrameWork向開發人員提供了豐富的API用於實現各種各樣的動畫效果,而若要對動畫分類,一般可將Android動畫分為以下兩類的動畫系統:
View Animation
View Animation動畫系統又可以分類成Tween Animation 和Frame Animation:
Tween Animation
Tween Animation是Android系統比較老的一種動畫系統,它的特點是通過對場景里的對象不斷做圖像變換(漸變、平移、縮放、旋轉)產生動畫效果,且這種動畫只適用於View對象。
Frame Animation
Frame Animation也是常用到的動畫,它的原理比較簡單,就是將一系列准備好的圖片按照順序播放,形成動畫效果。
Property Animation
Property Animation(屬性動畫)是在Android3.0(API 11)之後引入的一種動畫系統,該動畫提供了比View Animation更加豐富、強大和靈活的功能,Android官方推薦開發人員使用該動畫系統來實現動畫。Property Animation的特點是動態地改變對象的屬性從而達到動畫效果。該動畫實現使用於包括View在內的任何對象。

Tween Animation
了解到Tween Animation是Android中比較老的一種動畫系統,且其只能實現對View對象動畫設置,不過其雖然沒有Property Aniamtion功能那麼強大和靈活,但是使用Tween Animation依然能完成日常大部分的開發需求。靈活地掌握Tween Animation的使用方法,十分有必要。那Tween Animation實現View的動畫,一般分為以下幾種效果:
Alpha:漸變透明動畫效果;
Scale:漸變尺寸伸縮動畫效果;
Translate:位置位移動畫效果;
Rotate:位置旋轉動畫效果。
接下來通過實例來一一學習如何實現以上幾種動畫效果,實現Tween Animation分為xml實現和代碼實現,下面會分別使用這兩種方式來實現上面的的幾種動畫效果。首先使用xml方式來實現View的Alpha漸變透明動畫效果,在項目目錄結構中創建res/anim文件夾,然後在文件夾中創建view_animation_alpha.xml文件,文件中的代碼如下:
[html] view plain


<!--
* android:interpolator:修飾動畫效果,定義動畫的變化率,可以使存在的動畫效果accelerated(加速),
* decelerated(減速),repeated(重復),bounced(彈跳)等。
* android:fromAlpha="0.0":設置動畫開始時控制項的透明度,0.0為透明,控制項不顯示,1.0為不透明,控制項全部顯示
* android:toAlpha="1.0":設置動畫結束時的控制項的透明度
* android:ration="2500":設置每一次動畫持續的時間值
* android:repeatCount="5":設置動畫重復的次數
* android:repeatMode="reverse":設置動畫重復的模式,reverse為0.0 -> 1.0 -> 0.0,動畫反復執行;
* restart為0.0 -> 1.0, 0.0 -> 1.0,動畫每次都重新開始執行
-->
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:ration="2500"
android:repeatCount="5"
android:repeatMode="reverse"
/>
xml文件中的屬性在代碼中都有詳細的解釋,這里就不重復說明了。定義完XML文件後,然後在代碼中使用AnimationUtils類調用loadAnimation(context, id)方法來載入xml文件,具體代碼如下:
[java] view plain


/**
* xml文件載入圖片漸變(Alpha)動畫
*/
Animation mAnimation = AnimationUtils.loadAnimation(this, R.anim.view_animation_alpha);
上面是使用xml實現Alpha的動畫效果,下面我們來看看如何在代碼中實現Alpha的動畫,很簡單,只需要實例化一個AlphaAnimation對象,然後傳遞相關參數就行,具體代碼如下:
[java] view plain


/**
* 代碼創建圖片漸變(Alpha)動畫
* 實例化AlphaAnimation對象:
* mAnimation = new AlphaAnimation(fromAlpha, toAlpha);
* fromAlpha:設置動畫開始時控制項的透明度,0.0為透明,控制項不顯示,1.0為不透明,控制項全部顯示
* toAlpha:設置動畫結束時的控制項的透明度
*/

Animation mAnimation = new AlphaAnimation(0.0f, 1.0f);
分別使用xml和代碼實現Alpha動畫後,最後為一個ImageView對象設置創建好的Alpha動畫,ImageView對象只需要調用startAnimation(Animation animation)方法,將剛剛創建好的alpha動畫對象作為參數添加傳進去搞定,具體代碼如下:
[java] view plain


ImageView mImageView = (ImageView)findViewById(R.id.view_animation_imageview);
//設置控制項開始執行動畫
mImageView.startAnimation(mAnimation);

I. Android屬性動畫之旋轉動畫

CSDN同步發布

旋轉動畫有三種

角度增加是逆時針方向旋轉。注意,如果旋轉角度是90度的話,最終View會不可見。

當要旋轉的View尺寸很小的時候,效果很好,但是當View很大的時候,就出問題了。如下所示:

當時很奇怪為啥會這樣呢?最後是在這篇文章 實現翻轉卡片的動畫效果 看到了一個叫cameraDistance的東西,然後感覺可能這個有用,試了試果然可以。

View的 getCameraDistance 方法。

View的 setCameraDistance 方法,看注釋。

注意:注釋中的這段這個相源襲機距離用「深度像素」來表示。默認的距離依賴屏幕的密度。例如,在一個中等沒裂棗密度的屏幕上,默認的距離是1280。在高密度的屏幕上,默認距離是1920。我認為這個單位是dp。1280dp,1920dp。我的測試機density是2.75,通過getCameraDistance方法,獲枯拆取到的值是3520.0,3520.0除以2.75就是1280。

注意:關於設置cameraDistance,建議始終使用大於此視圖高度(繞X軸旋轉)或寬度(Y軸旋轉)的相機距離。而且這個距離得比較大才行,我測試下來得10000以上才可以。如下所示:

同樣需要設置 cameraDistance

平時這個用的比較多應該,也比較簡單。也不涉及 cameraDistance 的東西。

參考鏈接

熱點內容
trimsql 發布:2024-03-29 23:29:13 瀏覽:691
編程自學書 發布:2024-03-29 23:29:08 瀏覽:377
qq密碼在qq哪裡能看見 發布:2024-03-29 23:29:06 瀏覽:214
楚雄琪豐酒店wifi密碼多少 發布:2024-03-29 23:20:10 瀏覽:509
自招編程題 發布:2024-03-29 23:19:31 瀏覽:192
蘋果端的什麼游戲與安卓數據互通 發布:2024-03-29 23:18:23 瀏覽:695
androidwear表盤 發布:2024-03-29 23:09:46 瀏覽:833
19萬的紅旗有哪些配置 發布:2024-03-29 23:09:44 瀏覽:985
裝修公司網站源碼 發布:2024-03-29 23:01:45 瀏覽:454
安卓手機哪個有nfc功能 發布:2024-03-29 22:59:25 瀏覽:554