Android 2.2
本篇不考慮非圖片式的動畫(如:動態畫點、線、面)
-----------------
名詞解說
SurfaceView:
SurfaceView本身是一個View物件,並提供canvas(畫布)來達成動畫的效果。一般來說,SurfaceView會搭配一個Thread來更新canvas。也就是,SurfaceView會透過畫布更新的方式來表現動畫。
Animation:
Animation本身不是一個View物件,因此必須搭配一個View(該View本身需指定Drawable物件)來達成動畫的效果。也就是,Animation是一種動畫效果,只要把該效果指定給某個View即可。
Animation又分Tween Animation及Frame Animation。
- Tween Animation:宣告一個set的效果。在set裡包括alpha(透明度變化)、scale(大小變化)、translate(位置移動)及rotate(旋轉),該四種效果可分開或合併觸發,或是依時觸發。
- Frame Animation:宣告一個animation-list,在list裡面則放入item,並指定item的drawable及持續時間。Android會依序程現item。
共同點/共通問題點:
資源管理:
主要的資源管理工作會花在Drawable的取用。因Drawable的資源名稱無法靠程式來正確取得,因此一般來說我會用HashMap
動畫流程計算及管理:
雖然Animation不需去計算動畫更新的細節,但仍可透過AnimationListener來管理動畫onAnimationStart(開始)/onAnimationEnd結束/onAnimationRepeat重覆事件。(注意:Frame Animation無法管理這些事件)。SurfaceView則必須實作動畫更新的所有細節。
人機互動 OnTouchListener/OnGestureListener事件 :
onTouchEvent(手指觸碰事件)及GestureDetector(手指滑動偵測)。SurfaceView本身是一個View因此可接收及實作此類事件,而Animation則要透過其他的View來接收事件(如主要的ContentView)。不管如何,在事件觸發後,都要實作相關的運算來決定動畫呈現的方式。
應用上如何取捨:
<在不考慮效能及動畫更新速度的情況下>
SurfaceView:
動態更新的動畫。例如,圖片會隨著使用者的手部移動而移動。 固定時間更新的動畫, 如:圖片隨時間改變。 在更新過程中有邏輯判斷來決定更新的方式/內容 遊戲類程式
Animation:
固定展示的動畫。 不想自行實作運算移動距離、時間及旋轉角度等問題時。 想表現簡單的動畫在非遊戲類別的程式中
個人心得:
SurfaceView:
可控制的細節相當深入,因此可實現Animation做不到的變化,但其編碼較複雜,且要考慮canvas及thread的管理。若要和畫面上的其他View互動則只能透過callback或是傳送參考至SurfaceView的方式來進行操作。程式碼維護相對困難。處理surfaceCreated()、surfaceChanged()、surfaceDestroyed()事件時要相當小心,否則容易出錯在畫布更新。
因自由性相當高,若能進階使用GLSurfaceView(ex: 3D特效)則應可寫出任何想要的動畫效果。另外,雖說一個畫面中是可放入多個SurfaceView,但實作中發現thread會變的難以控制,尤其是SurfaceView(s)間還要互動時。因此建議擺一個即可。
小技巧:
若在SurfaceView上還想放其他的View,但卻被背景遮著,可透過Paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR))的方式來將SurfaceView的背景變透明。並設定 SurfaceView.getHolder().setFormat(PixelFormat.RGBA_8888); SurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT); SurfaceView.setZOrderOnTop(true);
每一張圖片的位置都要記錄並運用MotionEvent.getX()及getY()來判斷使用者是否有按到圖片,及按到的是那一張圖片。
為了避免不同尺寸下,SurfaceView畫出來的圖片和其他的View位置會混亂,建議在onCreate()的時後去排定其他的View的大小及位置,而不是在xml檔案裡指定view的大小及位置。
在doDraw中運用state-machine的方式來呈現動畫可減少許多的設計錯誤。記得要先畫state-machine的圖再實作。
Animation:
簡單,易用。
Animation可在xml中設定,也可以在程式中動態實作類別。但似乎無法在程式中讀入Animation xml資源再進行動態細節更改,目前只能更改set or animation-list的參數,尚未找到方法更改其包括其他node的參數(有待商確)。
動畫範圍和View設定的大小坐標有關,但可透過+/-的方式來讓動畫超出View的範圍(假設View比Activity畫面小,則超出的部份效果仍然可見)。
對一個ImageView來說,Frame Animation可設定在ImageView.setBackgroundDrawable(背景)或是ImageView.setImageDrawable(前景),效果相同,但若前景有圖片時,則背景效果不會出現。
Animation不能在onCreate()時啟動,因此時View的實作尚未完成。
若要將動畫運用在Activity切換,則:
Intent intent=new Intent(main.this,nextActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.amFrom,R.anim.amTo);
被動畫效果移動的物件是不會停留在結束位置的。
即使fillAfter="true"也只是視覺上的停留在該點,實際位置則是回到了初始值。
沒有留言:
張貼留言