Android開發——View動畫、幀動畫和屬性動畫詳解
0. 前言
Android動畫是面試的時候經常被問到的話題。我們都知道Android動畫分為三類:View動畫、幀動畫和屬性動畫。
先對這三種動畫做一個概述:
View動畫是一種漸進式動畫,定義動畫開始和結束的兩幀,並指定動畫變化的時間和方式。並通過平移、縮放、旋轉和透明度四種效果結合成複雜的動畫效果。而在開始和結束幀之間插入的漸變值依據的是插值器。
幀動畫是通過不停的切換圖片實現動畫效果。
屬性動畫是不停的改變物件的屬性來實現動畫效果。4.4新出的過渡動畫只是對屬性動畫的一層封裝。
1. View動畫
1.1 系統提供的四種View動畫(補間動畫)
View動畫可以在res/anim/name.xml檔案裡進行配置,四種
view.startAnimation(AnimationUtils.loadAnimation(this,R.anim.myanimation));
這些當然也可以在Java程式碼裡進行配置,也比較簡單,這裡寫了一個示例程式碼:
splash = (RelativeLayout)findViewById(R.id.splash); //旋轉動畫 RotateAnimation rotateAnimation = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); rotateAnimation.setDuration(2000); rotateAnimation.setFillAfter(true); //縮放動畫 ScaleAnimation scaleAnimation = new ScaleAnimation(0,1,0,1, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); scaleAnimation.setDuration(2000); scaleAnimation.setFillAfter(true); //漸變動畫 AlphaAnimation alphaAnimation = new AlphaAnimation(0.2f,1.0f); alphaAnimation.setDuration(2000); alphaAnimation.setFillAfter(true); //平移動畫 TranslateAnimation translateAnimation = newTranslateAnimation (0,0,100,100); translateAnimation.setDuration(2000); translateAnimation.setFillAfter(true); //動畫集合 AnimationSet animationSet = new AnimationSet(true); animationSet.addAnimation(rotateAnimation); animationSet.addAnimation(scaleAnimation); animationSet.addAnimation(alphaAnimation); animationSet.addAnimation(translateAnimation); //啟動動畫 plash.startAnimation(animationSet);
1.2 自定義View動畫
實際專案中,如果四種基本動畫無法滿足需求,就需要自定義補間動畫了。
完成自定義動畫需要繼承Animation類,並重寫其initialize()以及applyTransformation()。前者用於一些初始化的操作,後者用於進行矩陣變換。
1.3 為ViewGroup的所有子元素設定動畫
上面1.1,1.2都是給View設定動畫效果,Android同樣提供了為ViewGroup設定android:layoutAnimation=”@anim/layout_anim”來達到給ViewGroup中所有子元素設定動畫的目的。下面給出相關程式碼:
//res/anim/anim/layout_anim.xml <layoutAnimation xmlns:android=” http://schemas.android.com/apk/res/android” android:delay=”0.1” //動畫延遲時間為0.1*T,本例為100ms android:animationOrder=”normal” //子元素的播放動畫順序為順序,也有reverse以及random android: animation=” @anim/layout_anim_item”/> //res/anim/anim/layout_anim_item.xml <?xml version=”1.0” encoding=”utf-8”?> <set xmlns:android=”http://schemas.android.com/apk/res/android” animation:duration=”200” //每個子元素的動畫週期T animation:interpolator=”@android:anim/accelerate_ interpolator” //指定插值器 animation:shareInterpolator=”true”> //表示所有子元素共享該插值器 <alpha android:fromAlpha=”0.2” android: toAlpha =”1.0”/> <translate android:fromXDelta=”100” android: toXDelta =”0”/> </set>
1.4 為Activity切換設定動畫
估計大家也都用過,在startActivity()之後使用,使Activity切換時達到一個平移的動畫效果:
overridePendingTransition(R.anim.tran_in,R.anim.tran_out);
//res/anim/tran_in
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
//表示從螢幕100%的位置開始,因此tran_out當然是toXDelta="-100%p",其他不變
android:fromXDelta="100%p"
android:fromYDelta="0"
android:toXDelta="0"
android:toYDelta="0" >
</translate>
2. 幀動畫
上面也提到了,幀動畫就是不停的切換圖片實現動畫效果。很明顯容易OOM,所以使用幀動畫要注意圖片大小。
幀動畫的使用也很簡單,使用示例如下:
//res/drawable/myanimation.xml
<?xml version=”1.0” encoding=”utf-8”?>
<animation-list xmlns:android=”http://schemas.android.com/apk/res/android”
animation:oneshot=”false” > //false為迴圈播放,true為類似於View動畫的setFillAfter效果
<item android: drawable =”@ drawable/ drawable 1” android:duration=” 200”>
<item android: drawable =”@ drawable/ drawable 2” android:duration=” 200”>
</animation-list>
//在程式碼里加載動畫設定並啟動動畫
view.setBackgroundResource(R.drawable.myanimation.xml);
(AnimationDrawable)view.getBackground.start();
3. 屬性動畫
View動畫的那四種效果有很明顯的缺點,繪製出來的效果其實並沒有真正改變View的屬性,即left、top、right和bottom的值,只是系統臨時繪製的結果。這樣View的點選位置並沒有發生變化。針對這個問題,從Android3.0開始屬性動畫應運而生。
屬性動畫本質是通過改變新增的屬性(如平移translationX/Y、縮放scaleX/Y、旋轉rotationX/Y等)並重新整理螢幕來實現動畫效果,並且實現點選位置的實時改變。但是屬性動畫仍然不會修改原始的上下左右四個值。最後需要注意的是,屬性動畫不止用於View,還可以用於任何物件。
下面介紹與屬性動畫相關的類和方法:
3.1 setTranslationX方法
該方法直接更改view屬性的方法,因為有時候不需要使用動畫效果。
view.setTranslationX(x);//3.0以後
ViewHelper.setTranslationX(view,x);//3.0以前通過NineOldAndroid庫實現
3.2 ValueAnimator類
ValueAnimator只定義和執行動畫流程,並沒有直接操作屬性值的邏輯,需要新增動畫更新的監聽,並在onAnimationUpdate()中執行自定義的動畫邏輯。
ValueAnimator animator = ValueAnimator.ofInt(1, 100); //定義動畫,相當於1秒內數100個數
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation){
float fraction = animation.getAnimatedFraction();//動畫進度值0-1
//整型估值器幫我們計算了start+(end-strat)*fraction,並設定給控制元件的寬度
view.getLayoutParams().width = new IntEvaluator().evaluate(fraction,start,end) //不需要set方法
view.requestLayout();
}
});
animator.setDuration(1000).start();
3.3 ObjectAnimator類
ObjectAnimator繼承自ValueAnimator,它允許直接改變view的屬性,下面通過一個例子介紹。
//x軸方向縮放的例子
ObjectAnimator animator = ObjectAnimator.ofFloat(view,”scaleX”,2.0f);
animator.setDuration(1000);
animator.setStartDelay(1000);
animator.start();
大多數的情況使用ObjectAnimator就足夠了,因為它不用像ValueAnimator那樣自己寫動畫更新的邏輯,但是ObjectAnimator有一定的限制——它需要目標屬性提供指定的處理方法(譬如提供get/set方法),這是因為ObjectAnimator的原理是不停的呼叫set方法更新屬性值,並且如果我們沒有傳遞初始值,系統會直接呼叫get方法獲取值。而上面3.2中介紹過的ValueAnimator則不直接操作屬性值,所以要操作物件的屬性可以不需要se/get方法,你完全可以通過當前動畫的計算去修改任何屬性。
針對這個問題,官方推薦我們用一個類包裝原始物件,間接為其提供get/set方法,實現起來很簡單,例項如下:
ViewWrapper wrapper = new ViewWrapper(view);
ObjectAnimator.ofInt(wrapper,”width”,200).setDuration(1000).start();
private static class ViewWrapper{
private View myView;
public ViewWrapper(View view){
myView = view;
}
public int getWidth(){
return myView.getLayoutParams().width;
}
public int setWidth(int width){
myView.getLayoutParams().width = width;
myView.requestLayout();
}
}
3.4 ViewPropertyAnimation類
ViewPropertyAnimation是NineOldAndroid庫中的類,簡化了ObjectAnimator類的操作,並且NineOldAndroid庫相容了3.0以前的Android版本。下面經過一個例子介紹。
//x軸方向縮放的例子,效果同3.3
ViewPropertyAnimation.animate(view).scaleX(2.0f).setDuration(1000)
.setInterpolator(new OvershootInterpolator())
.setStartDelay(1000).start();
3.5 AnimationSet類
動畫集合,提供把多個動畫組合成一個組合的機制,並可設定動畫的時序關係,如同時播放、順序播放或延遲播放。具體使用方法比較簡單,如下所示:
ObjectAnimator objectAnimator1= ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0f);
ObjectAnimator objectAnimator2= ObjectAnimator.ofFloat(view, "translationY", 0f, 30f);
ObjectAnimator objectAnimator3= ObjectAnimator.ofFloat(view, "translationX", 0f, 30f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(5000);
animatorSet.setInterpolator(new LinearInterpolator());
// animatorSet.playTogether(objectAnimator1, objectAnimator2. objectAnimator3); //三個動畫同時執行
// 12同時執行,3接著執行
animatorSet.play(objectAnimator1).with(objectAnimator2);
animatorSet.play(objectAnimator3).after(objectAnimator2);
animatorSet.start();
4. 插值器總結
4.1 系統已經提供給我們的插值器
各種插值器都是實現了Interpolator介面,下面來看一下系統已經提供給我們直接使用的插值器。
4.2 自定義插值器
Interpolator都實現了Interpolator介面,而Interpolator介面又繼承自TimeInterpolator,TimeInterpolator介面定義了一個由系統呼叫的getInterpolation(float input)方法,其中引數input代表動畫完成進度,在0和1之間。我們自定義插值器只需要實現Interpolator介面並覆寫getInterpolation()方法即可實現自定義的動畫效果。
如下就是一個動畫始末速率較慢、中間加速的AccelerateDecelerateInterpolator插值器:
public class AccelerateDecelerateInterpolator extends BaseInterpolator
implements NativeInterpolatorFactory {
......
public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}
......
}
5. 動畫監聽器
我們在平時開發過程中,經常要監聽動畫完成的時機以繼續業務邏輯,那麼我們可以通過給動畫集合設定AnimationListener監聽器來實現。分別可以監聽動畫開始、結束、取消以及重複播放。
//監聽動畫完成
animationSet.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationCancel(Animation animation) {}
});
最後若想監聽動畫中每一幀的回撥,我們可以設定AnimatorUpdateListener監聽器並重寫其onAnimationUpdate()方法即可。
至此關於Android動畫的知識總結完畢。相關推薦
Android Drawable資源中selector、layer-list和shape標籤詳解
在實際開發中,我們經常會對控制元件的樣式進行一些修改已滿足我們的要求,這時候就會引用 Drawable 資源的樣式檔案。 1、StateListDrawable 資源 StateListDrawable 用於組織多個 Drawable 物件。當使用 Stat
原碼、反碼和補碼的詳解
原碼 原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其餘位表示值. 比如如果是8位二進位制: [+1]原 = 0000 0001 [-1]原 = 1000 0001 第一位是符號位. 因為第一位是符號位, 所以8位二進位制數的取值範圍就是: [1111 1111
裝置、裝置節點和裝置驅動詳解
1.裝置 Linux下的裝置通常分為三類,字元裝置,塊裝置和網路裝置。 裝置驅動程式也分為對應的三類:字元裝置驅動程式、塊裝置驅動程式和網路裝置驅動程式。 常見的字元裝置有滑鼠、鍵盤、串列埠、控制檯等。 常見的塊裝置有各種硬碟、flash磁碟、RAM磁碟等。 在
PHP中的單引號、雙引號和轉義字元詳解
PHP單引號及雙引號均可以修飾字符串型別的資料,如果修飾的字串中含有變數(例$name);最大的區別是: 雙引號會替換變數的值,而單引號會把它當做字串輸出。 轉義字元,顧名思義會將規定的語法用"\"來輸出。但語法規定在不同的系統中轉義字元的作用不同,例如:windows下的回車換行符用"\r"或"
WatchOS開發教程之三: 導航方式和控制元件詳解
導航方式 Watch App中導航樣式分為兩種:分頁樣式(Page based) 和分層樣式(Hierarchical), 這兩種樣式是互斥的,所以不能混合使用只能選擇其一。Hierarchical方式可以通過pushController或者prese
Dijkstra演算法、prim演算法和 Kruskal演算法詳解
1 Dijkstra演算法問題描述:在一個圖中,給定指定頂點,求該頂點到其它頂點的最短距離。如圖所示:這是一個有向圖,現在要求解從頂點V1到其它頂點的最短距離。以上圖為例,利用Dijkstra演算法求解最短距離。步驟:(1)將所有頂點分為兩組,一組是未知的即為S,一組是已知的
Java中編譯期、執行期、堆記憶體和棧記憶體詳解
java中記憶體分配策略及堆和棧的比較 1 記憶體分配策略 按照編譯原理的觀點,程式執行時的記憶體分配有三種策略,分別是靜態的,棧式的,和堆式的. 靜態儲存分配是指在編譯時就能確定每個資料目標在執行時刻的儲存空間需求,因而在編譯時就可以給他們分配固定的記憶體空間.這種分配策略要求程式程式碼中
Eureka的服務提供者、服務消費者和註冊中心詳解
一 架構圖二 服務提供者1 服務註冊“服務提供者”在啟動的時候會通過REST請求的方式將自己註冊到Eureka Server上,同時帶上自身服務的一些元資料資訊。Eureka Server接收到這個REST請求之後,將元資料資訊儲存在一個雙層結構Map中,其中第一層的key是
Spring之IOC、核心容器和Bean概念詳解
這一週忙了很多與程式碼無關的事,感覺心態上還是有些急躁,週中挑幾個晚上看了一些文章,上午起來總結了一下,下午開始寫部落格,因為沒有時間擼程式碼,所以就打算先把看到的概念梳理梳理,磨刀不誤砍柴工。 首先來看一看什麼是IOC,他的全稱是Inversion of Co
關於AngularJs中$http post、get 傳送和接受引數詳解
1、POST、GET攜帶引數的寫法不一樣,如下: ? 1 2 3 4 5 6 7 $http({method: 'post', url: './feedback/ma
為什麼C++中常量引用可以繫結非常量的物件、字面值和一般表示式 詳解
在c++語言中,除兩種例外情況,其他引用的型別都要和與之繫結的物件嚴格匹配,如int型的引用只能繫結int型的物件;並且引用不能直接與字面值常量或表示式結果繫結。 其中一種例外情況是:初始化常量引用時,允許用任意表達式作為初始值,只要該表示式的結果能轉換成引用的
transition、transform 等css3屬性用法詳解
transition、transform 等css3屬性用法,如果掌握的好,使用起來能夠遊刃有餘,相信使用者體驗什麼的應該也不會差!具體頁面效果可看頁面右側的“打醬油的,各種路過”模組。沒錯!加這個效果上去,就是要把這些傢伙全部曝光,讓你們打醬油...
flex彈性佈局的屬性和屬性值詳解
一、Flex佈局是什麼? Flex是Flexible Box的縮寫,意為”彈性佈局”,用來為盒狀模型提供最大的靈活性。 任何一個容器都可以指定為Flex佈局。 .box{ display: flex; } 行內元素也可以使用Flex佈局。 .box{ dis
Android開發——View動畫、幀動畫和屬性動畫詳解
0. 前言Android動畫是面試的時候經常被問到的話題。我們都知道Android動畫分為三類:View動畫、幀動畫和屬性動畫。先對這三種動畫做一個概述:View動畫是一種漸進式動畫,定義動畫開始和結束
Android載入動畫 旋轉動畫 、幀動畫
android中的載入動畫 上程式碼: 這是使用方式: public class LoadingActivity extends AppCompatActivity { //載入動畫activity private Dialog loading;
android 開發 View _11_ xml動畫
一、概述 Android的animation由四種類型組成:alpha、scale、translate、rotate,對應android官方文件地址:《Animation Resources》 1、XML配置檔案中 alpha 漸變透明度動畫效果 scal
Android Animation、ObjectAnimator與ValueAnimator實現檢視動畫和屬性動畫
一、檢視動畫 檢視動畫比較簡單,它提供了AlphaAnimation、RotateAnimation、TranslateAnimation、ScaleAnimation四種動畫方式。 檢視動畫一個非常大的缺陷就是不具有互動性,當一個View發生檢視動畫後,其
View動畫、幀動畫、屬性動畫
轉載請註明出處,謝謝 View動畫: 1、View可以使用程式碼來設定也可以使用xml檔案來設定,在xml檔案裡面對應的標籤為: <translate>…………</translate
vue中動畫關鍵幀keyframes 和 animation 和animate動畫庫
(1) <style> @keyframes fontScale { 0% { font-size: 30px; } 100% { font-size: 50px; } }
Android開發 - 掌握ConstraintLayout(十一)複雜動畫!如此簡單!
介紹 本系列我們已經介紹了ConstraintLayout的基本用法。學習到這裡,相信你已經熟悉ConstraintLayout的基本使用了,如果你對它的用法還不瞭解,建議您先閱讀我之前的文章。 使用ConstraintLayout建立動畫的基本思想是我們建立兩個不同的佈局,每個佈局有其不同的約束,從而我