1. 如何高效學習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);
2. 安卓開發中矢量圖的繪制及動畫
矢量圖也稱為面向對象的圖像或繪圖圖像,是根據幾何特性來繪制的圖形,在安卓開發中可以使用失量圖代替原來的圖片資源,矢量圖具有佔用空間小和可以隨意縮放但不失真的優勢,在我的多個項目中都有運用。
通過學習和實踐,我總結了一些與矢量圖相關的知識,方便今後更好的使用矢量圖,同時也可以供大家查閱參考。
繪制矢量圖之前需要先定義畫布的寬高,後續的繪制效果都展示在這個畫布上。在繪制過程中需要輸入的坐標就是這個畫布上的點。
安卓的矢量圖常見於 drawable 文件夾下,是一個xml文件,由 vector 標簽包裹,在 vector 標簽中可包含多個 path 標簽,依次疊加顯示。
在矢量圖中最重要的就是 path 屬性,圖像的樣式就是由 path 屬性中的數據繪制而成,這些數據由不同的命令組合而成,下面就介紹一些矢量圖的繪制命令。
將前面的命令示例連接起來就可以生成一個完整的圖像,它大概長這個樣子:
畫布的尺寸為500x500,圖上的頂點是200,10的位置,也是我們開始作圖的起點。通過這個圖片可以更好的理解每一個繪圖命令。
安卓中可以為矢量圖添加動畫效果,這樣用戶就可以看到一個動的圖片,可以一定程度的提高app的交互效果。矢量圖動畫是圖形內部的變化,可以做到View動畫無法實現的效果。
這種動畫針對的是矢量圖中 path 欄位的值,通過連續改變 path 欄位的值而達到產生動畫的效果。
註:pathData動畫所需的AnimatedVectorDrawable最低要求API等級為25
實現一個矢量圖動畫需要以下幾步:
1. 准備起始狀態和結束狀態的矢量圖兩張。
2. 創建動畫配置文件。
3. 創建動畫矢量圖文件。
4. 啟動動畫。
基於這種要求,我准備了兩個矢量圖:
控制動畫運行的是一個 objectAnimator ,此處把 objectAnimator 包裹在一個 set 中也是可以的,說白了就是執行這個動畫文件。
ration 用來指定動畫的持續時間。
propertyName 中的pathData指的就是矢量圖中的pathData。
valueFrom 和 valueTo 一個是起始路徑,一個是結束路徑,可以想到,這個動畫就是在持續修改pathData,從而達到展示動畫的效果。而 valueFrom 和 valueTo 的值是直接從先前准備的矢量圖中復制過來的,所以那個結束狀態的矢量圖中唯一有用的東西就是pathData屬性,沒有那個文件也無所謂。
valueType 這里必須填判型寫pathType,這是專門用來計算path的類型。
此時,文件的最外層由 animated-vector 包裹,同時需要添加一個 drawable 參數,這個 drawable 用於指定動畫應用於那個矢量圖上,我們是要從未啟用狀態變成啟用狀態,所以是在未啟用狀態開始執行動畫,在動畫未開始的時候展示的也是未啟用狀態。此處我們指定為 @drawable/icon_filter_off 。
內部有一個 target 標簽,這個標簽可以有多個,分別對應不同的動畫,但同一個 path 只能應用一個動畫。
name 用於指定要執行動畫的 path 。status正是我們為右下角小圖標path設置的名稱。
animation 用於指定需要執行的動畫。此處引用我們剛剛創建的猛沖山動畫資源 @animator/filter_turn_on 。
當我們創建枝中好動畫矢量圖之後,頁面中引用的資源就不再是之前的靜態矢量圖了,需要把 ImageView 的圖片替換成 @drawable/animated_filter_on
經過這么多的步驟,我們終於做出了一個矢量圖動畫,而且是一個。說實話,有點累,然而我這個狀態切換的動畫一套就要兩個,所以我又加了一個回來的動畫和對應的動畫矢量圖,一共六個文件,完成了篩選狀態的兩個切換動畫。這還是比較簡單的實現方式,對於兩種狀態切換的動畫,網上還有一種使用selector的方式,這種方式更麻煩,而且使用方法並沒有簡單一些,所以我的選擇是在需要切換狀態的時候更改 ImageView 的圖片資源,然後再執行動畫。
trimPath動畫相當於是改變了矢量圖繪制的位置,是從頭開始畫還是從80%的位置開始畫,然後再動態的修改這個百分比,從而達到動畫的效果。理解起來倒不是很難。
先放一個我使用trimPath動畫做的loading效果,這個動畫效果被我用在LoadingDialog中,在界面載入的時候會重復播放這個動畫。
android:name="load" 不用多說,這個是我們做動畫時路徑名稱。這里為了讓心電圖路徑更清晰,我設置了描邊寬度為20( android:strokeWidth="20" ),同時還要設置描邊的顏色才能展示出來。後面的 android:trimPathStart="0" 和 android:trimPathEnd="0" 是本次trimPath動畫的重點。
這兩個屬性都設置為0是因為動畫的起始幀都為0,然後通過 objectAnimator 慢慢把這兩個屬性變為1,這樣一個慢慢增長的動畫就形成了。
網路上一個橫線變成搜索按鈕的示例是將這兩個屬性分別應用到了兩個 path 上,而我是將兩個屬性同時應用到一個 path 上,原理都是一樣的。
在配置文件中,我將兩個動畫都設置為3秒且循環播放,起始點的動畫慢於終點的動畫1秒,達到只畫中間1秒間隔線段的效果。和路徑變形動畫的區別是 android:valueType="floatType" ,我們只需要計算從0到1的數字,然後應用到 trimPathStart 和 trimPathEnd 欄位上。至此,loading的動畫就配置完了。
這一步已經沒什麼可說的了,就是將指定的矢量圖中指定的路徑設置一個指定的動畫。
通過幾天的學習,已經大致掌握了矢量圖的展示及動畫的製作,但這一套流程下來成本比較高,是程序員方式的動畫製作流程。除了製作成本,創意成本也是相當高的,一個好的創意能極大的提升用戶體驗,而好多時候我們的創意能夠被實現也是很困難的。希望以後能實現一些更好的效果,讓用戶使用起來更舒服。
SVG—最簡單的SVG動畫
SVG路徑(path)中的圓弧(A)指令的語法說明及計算邏輯
Android中的矢量圖
Android高級動畫(2)
3. Android 動畫效果為:月亮沿著橢圓形軌跡運行
我這里有個android的動畫效果集合
包括Activity轉跳,控制項,listview等等的動畫源代碼
你可以下載來看看
4. android 自定義圓怎麼動態設置圓的半徑
使用ObjectAnimation,或者ValueAnimation都可以實現這個效果
ObjectAnimation可以動態設置控制項有get與set方法的屬性進行改變,給你的圓添加一個半徑的屬性,並添加get與set。
參考
//通過AnimatiorSet來設計同步執行的多個屬性動畫
ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView, "translationX", 0F, 360F);//X軸平移旋轉
ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView, "translationY", 0F, 360F);//Y軸平移旋轉
ObjectAnimator animator3 = ObjectAnimator.ofFloat(imageView, "rotation", 0F, 360F);//360度旋轉
AnimatorSet set = new AnimatorSet();
//set.playSequentially(animator1, animator2, animator3);//分步執行
//set.playTogether(animator1, animator2, animator3);//同步執行
//屬性動畫的執行順序控制
// 先同步執行動畫animator2和animator3,然後再執行animator1
set.play(animator3).with(animator1);
set.play(animator2).after(animator3);
set.setDuration(1000);
set.start();
2.通過ValueAnimation來動態改變圓半徑的屬性
參考
public void onClick(View view) {
final ValueAnimator animator = ValueAnimator.ofInt(1, 100);
animator.setDuration(5000);
animator.setInterpolator(new LinearInterpolator());//線性效果變化
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
Integer integer = (Integer) animator.getAnimatedValue();
button.setText("" + integer);
}
});
animator.start();
}
5. Android 圓角、圓形 ImageView 實現
我們要實現的圖片控制項繼承自 AppCompatImageView ,它是 ImageView 的子類,但提供了更好的兼容性,我們在此基礎上添加了若干自定義的屬性和方法以實現最終的 NiceImageView :
要實圓角或者圓形的顯示效果,就是對圖片顯示的內容區域進行「裁剪」,只顯示指定的區域即可。如何做呢?
一種比較直接的辦法是這樣的,由於圖片是被繪制在畫布上的,所以用 canvas 的 clipPath() 方法先將畫布裁剪成指定形狀,這樣就能讓圖片按指定形狀顯示了,重新 draw() 方法即可:
這樣使用 src 、 background 屬性給ImageView設置顯示的圖片都能達到預期的顯示效果。但是由於 clipPath() 方法不支持抗鋸齒,圖片邊緣會有明顯的毛糙感,體驗並不理想,所以需要尋找其它方法。
另一種方法是使用圖像的 Alpha 合成模式 ,即
PorterDuff 來實現, 官方文檔 。這里我們使用其中的 DST_IN 模式。整個過程就是先繪制目標圖像,也就是圖片;再繪制原圖像,即一個圓角矩形或者圓形,這樣最終目標圖像只顯示和原圖像重合的區域。
到這里就實現了顯示為圓角或者圓形了。但是需要通過 src 屬性或者對應的方法來設置圖片,否則不能達到預期效果。
繪制邊框就相對容易理解了,只需要繪制一個指定樣式的圓角矩形或者圓形即可:
當圖片顯示為圓形時,還可以繪制一個內邊框,但圓角矩形的話由於圓角大小的問題,目前只能設置一個邊框咯。
但是有個問題,繪制的邊框會覆蓋在圖片上,如果邊框太寬會導致圖片的可見區域變小了,影像顯示效果,像這樣,左下角的花盆不見了:
那麼如何讓邊框不覆蓋在圖片上呢?可以在 Alpha 合成繪制前先將畫布縮小一定比例,最後再繪制邊框,這樣問題就解決了。
縮放後的ImageView顯示區域的寬高就是原寬、高分別減去2倍的邊框寬度,這樣縮小的比例也就顯而易見了。效果如下,左下角的花盆出來了:
遮罩可以理解為一層帶透明度的顏色,遮罩默認不繪制,當制定了遮罩顏色時才會繪制,實現很簡單:
例如加一個透明度30%的紅色遮罩後的效果:
核心的實現邏輯就這些了,剩下的就是自定義屬性和方法了,有興趣的可以看源碼,都很簡單,希望對你有所幫助吧!
更多細節及用法見GitHub: https://github.com/SheHuan/NiceImageView
如果你需要實現類似釘釘的圓形組合頭像,例如:
6. Android中的幾種動畫
幀動畫:指通過指定每一幀的圖片和播放時間,有序的進行播放而形成動畫效果,比如想聽的律動條。
補間動畫:指通過指定View的初始狀態、變化時間、方式,通過一系列的演算法去進行圖形變換,從而形成動畫效果,主要有Alpha、Scale、Translate、Rotate四種效果。注意:只是在視圖層實現了動畫效果,並沒有真正改變View的屬性,比如滑動列表,改變標題欄的透明度。
屬性動畫:在Android3.0的時候才支持,通過不斷的改變View的屬性,不斷的重繪而形成動畫效果。相比於視圖動畫,View的屬性是真正改變了。比如view的旋轉,放大,縮小。
7. Android 旋轉動畫
<rotate
android:fromDegrees="45"//起始旋轉的角度
android:toDegrees="89"//結束選裝後的角度
android:ration="500"//執行時間為500ms
android:pivotX="50%"//距離控制項左邊緣50%
android:pivotY="50%"//距離控制項上邊緣50%(與上邊結合就是控制項中心)
android:fillEnabled="true"
android:fillAfter="true"//動畫執行完後停留在執行完的狀態
/>
—————————————————————————————————————————
當然也可以通過代碼用animation實現
好久沒寫,應該是
RotateAnimationanimation=newRotateAnimation(0f,45f,Animation.RELATIVE_TO_SELF,
0.5f,Animation.RELATIVE_TO_SELF,0.5f);
animation.setDuration(500);
view.setAnimation(animation);
8. 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通過監聽動畫過程,自己改變對象屬性完成動畫