Android動(dòng)畫(huà)之漸變動(dòng)畫(huà)(Tween Animation)詳解 (漸變、縮放、位移、旋轉(zhuǎn))
本文實(shí)例講述了Android動(dòng)畫(huà)之漸變動(dòng)畫(huà)(Tween Animation)。分享給大家供大家參考,具體如下:
Android 平臺(tái)提供了兩類(lèi)動(dòng)畫(huà)。 一類(lèi)是Tween動(dòng)畫(huà),就是對(duì)場(chǎng)景里的對(duì)象不斷的進(jìn)行圖像變化來(lái)產(chǎn)生動(dòng)畫(huà)效果(旋轉(zhuǎn)、平移、放縮和漸變)。
第二類(lèi)就是 Frame動(dòng)畫(huà),即順序的播放事先做好的圖像,與gif圖片原理類(lèi)似。
下面就講一下Tweene Animations。
主要類(lèi):
Animation 動(dòng)畫(huà)
AlphaAnimation 漸變透明度
RotateAnimation 畫(huà)面旋轉(zhuǎn)
ScaleAnimation 漸變尺寸縮放
TranslateAnimation 位置移動(dòng)
AnimationSet 動(dòng)畫(huà)集
有了這些類(lèi),那么我們?nèi)绾蝸?lái)實(shí)現(xiàn)動(dòng)畫(huà)效果呢?
以自定義View為例,該View很簡(jiǎn)單,畫(huà)面上只有一個(gè)圖片。 現(xiàn)在我們要對(duì)整個(gè)View分別實(shí)現(xiàn)各種Tween動(dòng)畫(huà)效果。
AlphaAnimation
通過(guò)代碼實(shí)現(xiàn) AlphaAnimation,如下:
//初始化 Animation alphaAnimation = new AlphaAnimation(0.1f, 1.0f); //設(shè)置動(dòng)畫(huà)時(shí)間 alphaAnimation.setDuration(3000); this.startAnimation(alphaAnimation);
其中AlphaAnimation類(lèi)第一個(gè)參數(shù)fromAlpha表示動(dòng)畫(huà)起始時(shí)的透明度, 第二個(gè)參數(shù)toAlpha表示動(dòng)畫(huà)結(jié)束時(shí)的透明度。
setDuration用來(lái)設(shè)置動(dòng)畫(huà)持續(xù)時(shí)間。
RotateAnimation
代碼:
Animation rotateAnimation = new RotateAnimation(0f, 360f); rotateAnimation.setDuration(1000); this.startAnimation(rotateAnimation);
其中RotateAnimation類(lèi)第一個(gè)參數(shù)fromDegrees表示動(dòng)畫(huà)起始時(shí)的角度, 第二個(gè)參數(shù)toDegrees表示動(dòng)畫(huà)結(jié)束時(shí)的角度。
另外還可以設(shè)置伸縮模式pivotXType、pivotYType, 伸縮動(dòng)畫(huà)相對(duì)于x,y 坐標(biāo)的開(kāi)始位置pivotXValue、pivotYValue等。
ScaleAnimation
代碼:
//初始化 Animation scaleAnimation = new ScaleAnimation(0.1f, 1.0f,0.1f,1.0f); //設(shè)置動(dòng)畫(huà)時(shí)間 scaleAnimation.setDuration(500); this.startAnimation(scaleAnimation);
ScaleAnimation類(lèi)中
第一個(gè)參數(shù)fromX ,第二個(gè)參數(shù)toX:分別是動(dòng)畫(huà)起始、結(jié)束時(shí)X坐標(biāo)上的伸縮尺寸。
第三個(gè)參數(shù)fromY ,第四個(gè)參數(shù)toY:分別是動(dòng)畫(huà)起始、結(jié)束時(shí)Y坐標(biāo)上的伸縮尺寸。
另外還可以設(shè)置伸縮模式pivotXType、pivotYType, 伸縮動(dòng)畫(huà)相對(duì)于x,y 坐標(biāo)的開(kāi)始位置pivotXValue、pivotYValue等。
TranslateAnimation
代碼:
//初始化 Animation translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f); //設(shè)置動(dòng)畫(huà)時(shí)間 translateAnimation.setDuration(1000); this.startAnimation(translateAnimation);
TranslateAnimation類(lèi)
第一個(gè)參數(shù)fromXDelta ,第二個(gè)參數(shù)toXDelta:分別是動(dòng)畫(huà)起始、結(jié)束時(shí)X坐標(biāo)。
第三個(gè)參數(shù)fromYDelta ,第四個(gè)參數(shù)toYDelta:分別是動(dòng)畫(huà)起始、結(jié)束時(shí)Y坐標(biāo)。
參數(shù)詳細(xì)說(shuō)明:
表二 |
||
XML節(jié)點(diǎn) | 功能說(shuō)明 | |
alpha | 漸變透明度動(dòng)畫(huà)效果 | |
<alpha android:fromAlpha=”0.1″ android:toAlpha=”1.0″ android:duration=”3000″ /> |
||
fromAlpha |
屬性為動(dòng)畫(huà)起始時(shí)透明度 |
0.0表示完全透明 1.0表示完全不透明 以上值取0.0-1.0之間的float數(shù)據(jù)類(lèi)型的數(shù)字 |
toAlpha | 屬性為動(dòng)畫(huà)結(jié)束時(shí)透明度 |
表三 |
|||
scale | 漸變尺寸伸縮動(dòng)畫(huà)效果 | ||
<scale android:interpolator= “@android:anim/accelerate_decelerate_interpolator” android:fromXScale=”0.0″ android:toXScale=”1.4″ android:fromYScale=”0.0″ android:toYScale=”1.4″ android:pivotX=”50%” android:pivotY=”50%” android:fillAfter=”false” android:startOffset=“700” android:duration=”700″ android:repeatCount=”10″ /> |
|||
fromXScale[float] fromYScale[float] | 為動(dòng)畫(huà)起始時(shí),X、Y坐標(biāo)上的伸縮尺寸 | 0.0表示收縮到?jīng)]有 1.0表示正常無(wú)伸縮 值小于1.0表示收縮 值大于1.0表示放大 |
|
toXScale [float] toYScale[float] |
為動(dòng)畫(huà)結(jié)束時(shí),X、Y坐標(biāo)上的伸縮尺寸 | ||
pivotX[float] pivotY[float] |
為動(dòng)畫(huà)相對(duì)于物件的X、Y坐標(biāo)的開(kāi)始位置 | 屬性值說(shuō)明:從0%-100%中取值,50%為物件的X或Y方向坐標(biāo)上的中點(diǎn)位置 | |
表四 |
|||
translate | 畫(huà)面轉(zhuǎn)換位置移動(dòng)動(dòng)畫(huà)效果 | ||
<translate android:fromXDelta=”30″ android:toXDelta=”-80″ android:fromYDelta=”30″ android:toYDelta=”300″ android:duration=”2000″ /> |
|||
fromXDelta toXDelta |
為動(dòng)畫(huà)、結(jié)束起始時(shí) X坐標(biāo)上的位置 | ||
fromYDelta toYDelta |
為動(dòng)畫(huà)、結(jié)束起始時(shí) Y坐標(biāo)上的位置 | ||
表五 |
|||
rotate | 畫(huà)面轉(zhuǎn)移旋轉(zhuǎn)動(dòng)畫(huà)效果 | ||
<rotate android:interpolator=”@android:anim/accelerate_decelerate_interpolator” android:fromDegrees=”0″ android:toDegrees=”+350″ android:pivotX=”50%” android:pivotY=”50%” android:duration=”3000″ /> |
|||
fromDegrees | 為動(dòng)畫(huà)起始時(shí)物件的角度 | 說(shuō)明 當(dāng)角度為負(fù)數(shù)——表示逆時(shí)針旋轉(zhuǎn) 當(dāng)角度為正數(shù)——表示順時(shí)針旋轉(zhuǎn) (負(fù)數(shù)from——to正數(shù):順時(shí)針旋轉(zhuǎn)) (負(fù)數(shù)from——to負(fù)數(shù):逆時(shí)針旋轉(zhuǎn)) (正數(shù)from——to正數(shù):順時(shí)針旋轉(zhuǎn)) (正數(shù)from——to負(fù)數(shù):逆時(shí)針旋轉(zhuǎn)) |
|
toDegrees | 屬性為動(dòng)畫(huà)結(jié)束時(shí)物件旋轉(zhuǎn)的角度 可以大于360度 | ||
pivotX pivotY |
為動(dòng)畫(huà)相對(duì)于物件的X、Y坐標(biāo)的開(kāi)始位 | 說(shuō)明:以上兩個(gè)屬性值 從0%-100%中取值 50%為物件的X或Y方向坐標(biāo)上的中點(diǎn)位置 |
|
答案是 AnimationSet。
初看整個(gè)類(lèi)名,還以為只是用來(lái)存放 Animation的一個(gè)Set, 細(xì)看才發(fā)現(xiàn),該類(lèi)也是繼承自 Animation的。
下面我們實(shí)現(xiàn)一個(gè)動(dòng)畫(huà),該動(dòng)畫(huà)會(huì)讓圖片移動(dòng)的同時(shí),圖片透明度漸變,直接看代碼吧。
//初始化 Translate動(dòng)畫(huà) translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f); //初始化 Alpha動(dòng)畫(huà) alphaAnimation = new AlphaAnimation(0.1f, 1.0f); //動(dòng)畫(huà)集 AnimationSet set = new AnimationSet(true); set.addAnimation(translateAnimation); set.addAnimation(alphaAnimation); //設(shè)置動(dòng)畫(huà)時(shí)間 (作用到每個(gè)動(dòng)畫(huà)) set.setDuration(1000); this.startAnimation(set);
是不是覺(jué)得很簡(jiǎn)單呢?
附上整個(gè)View類(lèi)的代碼吧。
package com.yfz.view; import com.yfz.R; import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.RotateAnimation; import android.view.animation.ScaleAnimation; import android.view.animation.TranslateAnimation; public class TweenAnim extends View { //Alpha動(dòng)畫(huà) - 漸變透明度 private Animation alphaAnimation = null; //Sacle動(dòng)畫(huà) - 漸變尺寸縮放 private Animation scaleAnimation = null; //Translate動(dòng)畫(huà) - 位置移動(dòng) private Animation translateAnimation = null; //Rotate動(dòng)畫(huà) - 畫(huà)面旋轉(zhuǎn) private Animation rotateAnimation = null; public TweenAnim(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Log.e("Tween", "onDraw"); //加載一個(gè)圖片 canvas.drawBitmap(((BitmapDrawable)getResources().getDrawable(R.drawable.gallery_photo_5)).getBitmap(), 0, 0, null); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { Log.e("Tween", "onKeyDown"); return true; } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { Log.e("Tween", "onKeyDown"); switch (keyCode) { case KeyEvent.KEYCODE_DPAD_UP: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_UP"); alphaAnimation = new AlphaAnimation(0.1f, 1.0f); //設(shè)置動(dòng)畫(huà)時(shí)間 alphaAnimation.setDuration(3000); this.startAnimation(alphaAnimation); break; case KeyEvent.KEYCODE_DPAD_DOWN: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_DOWN"); rotateAnimation = new RotateAnimation(0f, 360f); rotateAnimation.setDuration(1000); this.startAnimation(rotateAnimation); break; case KeyEvent.KEYCODE_DPAD_LEFT: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_LEFT"); //初始化 scaleAnimation = new ScaleAnimation(0.1f, 1.0f,0.1f,1.0f); //設(shè)置動(dòng)畫(huà)時(shí)間 scaleAnimation.setDuration(500); this.startAnimation(scaleAnimation); break; case KeyEvent.KEYCODE_DPAD_RIGHT: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_RIGHT"); //初始化 translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f); //設(shè)置動(dòng)畫(huà)時(shí)間 translateAnimation.setDuration(1000); this.startAnimation(translateAnimation); break; case KeyEvent.KEYCODE_DPAD_CENTER: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_CENTER"); //初始化 Translate動(dòng)畫(huà) translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f); //初始化 Alpha動(dòng)畫(huà) alphaAnimation = new AlphaAnimation(0.1f, 1.0f); //動(dòng)畫(huà)集 AnimationSet set = new AnimationSet(true); set.addAnimation(translateAnimation); set.addAnimation(alphaAnimation); //設(shè)置動(dòng)畫(huà)時(shí)間 (作用到每個(gè)動(dòng)畫(huà)) set.setDuration(1000); this.startAnimation(set); break; default: break; } return true; } }
在Activity中調(diào)用該類(lèi)時(shí),需要注意一定setFocusable(true), 否則焦點(diǎn)在Activity上的話,onKeyUp方法是不會(huì)生效的。
調(diào)用該View的代碼:
TweenAnim anim = new TweenAnim(Lesson_11.this); anim.setFocusable(true); setContentView(anim);
上面通過(guò)Java代碼,實(shí)現(xiàn)了4中不同的Tween動(dòng)畫(huà),其實(shí)在Android中完全可以通過(guò) XML文件來(lái)實(shí)現(xiàn)動(dòng)畫(huà)。這種方式可能更加簡(jiǎn)潔、清晰,也更利于重用。
下面我們分別對(duì)這幾種動(dòng)畫(huà)改用xml來(lái)實(shí)現(xiàn)。
首先是AlphaAnimation。
alpha_anim.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:fromAlpha="0.1" android:toAlpha="1.0" android:duration="2000" /> </set>
不用解釋了吧。
RotateAnimation
rotate_anim.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <rotate android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" android:duration="500" /> </set>
ScaleAnimation
scale_anim.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="0.0" android:toXScale="1.0" android:fromYScale="0.0" android:toYScale="1.0" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="500" /> </set>
TranslateAnimation
translate_anim.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="10" android:toXDelta="100" android:fromYDelta="10" android:toYDelta="100" /> </set>
布局文件都已經(jīng)寫(xiě)完,那么如何來(lái)使用這些文件呢?
其實(shí)也很簡(jiǎn)單,此時(shí)需要用到AnimationUtils類(lèi)。 通過(guò)該類(lèi)中 loadAnimation 方法來(lái)加載這些布局文件。
如:
這次View類(lèi)的代碼如下:
package com.yfz.view; import com.yfz.R; import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.AnimationUtils; import android.view.animation.RotateAnimation; import android.view.animation.ScaleAnimation; import android.view.animation.TranslateAnimation; public class TweenAnim2 extends View { //Alpha動(dòng)畫(huà) - 漸變透明度 private Animation alphaAnimation = null; //Sacle動(dòng)畫(huà) - 漸變尺寸縮放 private Animation scaleAnimation = null; //Translate動(dòng)畫(huà) - 位置移動(dòng) private Animation translateAnimation = null; //Rotate動(dòng)畫(huà) - 畫(huà)面旋轉(zhuǎn) private Animation rotateAnimation = null; public TweenAnim2(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Log.e("Tween", "onDraw"); //加載一個(gè)圖片 canvas.drawBitmap(((BitmapDrawable)getResources().getDrawable(R.drawable.gallery_photo_5)).getBitmap(), 0, 0, null); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { Log.e("Tween", "onKeyDown"); return true; } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { Log.e("Tween", "onKeyDown"); switch (keyCode) { case KeyEvent.KEYCODE_DPAD_UP: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_UP"); alphaAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.alpha_anim); this.startAnimation(alphaAnimation); break; case KeyEvent.KEYCODE_DPAD_DOWN: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_DOWN"); rotateAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.rotate_anim); this.startAnimation(rotateAnimation); break; case KeyEvent.KEYCODE_DPAD_LEFT: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_LEFT"); scaleAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.scale_anim); this.startAnimation(scaleAnimation); break; case KeyEvent.KEYCODE_DPAD_RIGHT: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_RIGHT"); translateAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.translate_anim); this.startAnimation(translateAnimation); break; case KeyEvent.KEYCODE_DPAD_CENTER: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_CENTER"); //初始化 Translate動(dòng)畫(huà) translateAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.translate_anim); //初始化 Alpha動(dòng)畫(huà) alphaAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.alpha_anim); //動(dòng)畫(huà)集 AnimationSet set = new AnimationSet(true); set.addAnimation(translateAnimation); set.addAnimation(alphaAnimation); //設(shè)置動(dòng)畫(huà)時(shí)間 (作用到每個(gè)動(dòng)畫(huà)) set.setDuration(1000); this.startAnimation(set); break; default: break; } return true; } }
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
相關(guān)文章
深入U(xiǎn)nderstanding Android ContentProvider詳解
本篇文章是對(duì)Android ContentProvider進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05詳解Android 檢測(cè)權(quán)限的三種寫(xiě)法
這篇文章主要介紹了詳解Android 檢測(cè)權(quán)限的三種寫(xiě)法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10Flutter?LinearProgressIndicator使用指南分析
這篇文章主要為大家介紹了Flutter?LinearProgressIndicator使用指南分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03android 有阻尼下拉刷新列表的實(shí)現(xiàn)方法
下面小編就為大家分享一篇android 有阻尼下拉刷新列表的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,一起跟隨小編過(guò)來(lái)看看吧2018-01-01Android中通過(guò)view方式獲取當(dāng)前Activity的屏幕截圖實(shí)現(xiàn)方法
這篇文章主要介紹了Android中通過(guò)view方式獲取當(dāng)前Activity的屏幕截圖實(shí)現(xiàn)方法,本文方法相對(duì)簡(jiǎn)單,容易理解,需要的朋友可以參考下2014-09-09Android開(kāi)發(fā)之PopupWindow創(chuàng)建彈窗、對(duì)話框的方法詳解
這篇文章主要介紹了Android開(kāi)發(fā)之PopupWindow創(chuàng)建彈窗、對(duì)話框的方法,結(jié)合實(shí)例形式詳細(xì)分析了Android使用PopupWindow創(chuàng)建對(duì)話框相關(guān)操作技巧,需要的朋友可以參考下2019-03-03Android room數(shù)據(jù)庫(kù)使用詳解
這篇文章主要介紹了Android room數(shù)據(jù)庫(kù)使用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-11-11Android UI設(shè)計(jì)之AlertDialog彈窗控件
這篇文章主要為大家詳細(xì)介紹了Android UI設(shè)計(jì)之AlertDialog彈窗控件的使用方法,感興趣的小伙伴們可以參考一下2016-08-08