星期四, 1月 26, 2012

Animation (八)

Android應用程式學習筆記

Animating Views

屬性動畫系統允許有效率的視圖物件的動畫,並提供一些超越視圖動畫系統的好處。視圖動畫系統藉由改變它們繪製地方法來變換視圖物件,在每個View容器中處理,因為View自己沒有屬性可以處理,結果View已經動畫了,但是View物件自己卻沒有改變。這造成物件的行為還留在原本的位置,雖然它已經繪製到不同位置了。

屬性動畫系統可以藉由改變視圖物件的真實屬性完成試圖物件在屏幕上的動畫,此外,視圖會在數值改變時自動呼叫invalidate()方法刷新屏幕,在View類別有新的屬性方便屬性動畫:
  • translationX與translationY:這些屬性控制視圖位置,它的左與頂部座標由它的布局容器設定。
  • rotation、rotationX與rotationY:這些屬性控制View在2D與3D下繞著支點的旋轉。
  • scaleX與scaleY:這些屬性控制View在2D下對於支點的伸縮。
  • pivotX與pivotY:這些屬性控制之點的位置,預設的支點值為View物件的中心位置。
  • x 與 y:這些屬性用來描述View物件在容器中位置。
  • alpha:顯示View物件的透明度,預設數值為1表示不透明,數值為0表示透明。
動畫一個View物件的屬性,比如顏色或是旋轉數值,所有你需要做的就是建立一個屬性animator,並指定你想動畫視圖動畫屬性。例如:

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);


Animating with ViewPropertyAnimator

使用一個單一的底層animator,ViewProperyAnimator提供了一個同時動畫一個View物件的許多屬性的簡單方式。它的行為很像一個ObjectAnimator,因為它確實改變了View物件的屬性,但當要同時動畫多個屬性時,ViewPropertyAnimator又更有效率。此外,使用ViewPropertyAnimator的程式碼更加簡潔與容易閱讀。以下程式碼片段顯示使用多個ObjectAnimator、單一ObjectAnimator與ViewPropertyAnimator同時動畫View的x與y屬性的不同。

Multiple ObjectAnimator objects
ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();
One ObjectAnimator
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
ViewPropertyAnimator
myView.animate().x(50f).y(100f);


Declaring Animation in XML

屬性動畫系統讓你用xml宣告屬性動畫,取代編成的方式。藉著在xml中定義動畫,你可以更輕易地重複在多個activities中重複使用,更輕鬆地編輯動畫序列。

為了區別使用新的屬性動畫APIs的動畫檔案與使用視圖動畫框架的,你應該將屬性動畫xml檔案存在res/animator目錄,使用animator目錄是自選的,如果你想要使用在eclipse ADT 的布局工具,你必須設定為animator,因為ADT只會在res/animator目錄搜尋屬性動畫。

以下是屬性動畫類別中支援xml的標籤:
  • ValueAnimator - <animator>
  • ObjectAnimator - <objectAnimator>
  • AnimatorSet - <set>


<set android:ordering="sequentially">
    <set>
        <objectAnimator
            android:propertyName="x"
            android:duration="500"
            android:valueTo="400"
            android:valueType="intType"/>
        <objectAnimator
            android:propertyName="y"
            android:duration="500"
            android:valueTo="300"
            android:valueType="intType"/>
    </set>
    <objectAnimator
        android:propertyName="alpha"
        android:duration="500"
        android:valueTo="1f"/>
</set>
為了運行此動畫,必須在妳的程式碼中將XML資源擴展到妳的Animator物件,並且在啟動前設定動畫的目標物件,呼叫serTarget()方法設定單一物件。

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
    R.anim.property_animator);
set.setTarget(myObject);
set.start();

Animation (七)

Android應用程式學習筆記

Using a TypeEvaluator

如果你想對Android系統來說為未知的型態動畫,你可以透過TypeEvaluator介面建立自己的evaluator實現動畫。Android系統所知的型態為int、float或是顏色,由IntEvaluator、FloatEvaluator、ArgbEvaluator型態的evaluator支援。

在TypeEvaluator介面中只有一個方法去執行,那就是evaluate()方法,此方法允許你正在使用的animator在當前的動畫中回傳適合的動畫屬性值。FloatEvaluator類別的實現:


public class FloatEvaluator implements TypeEvaluator {

    public Object evaluate(float fraction, Object startValue, Object endValue) {
        float startFloat = ((Number) startValue).floatValue();
        return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
    }
}


Using Interpolators

Interpolator用來定義動畫中的數值該如何計算。例如,你可以指定整段動畫線性地播放,意旨在整段時間中動畫平均地移動;或者指定動畫為非線性地動畫,比如,加速或是減速在動畫的開始或是結尾。

動畫系董中的Interpolators都會接收來自Animator用來表示動畫經過的時間的分數值,Interpolator修改此分數值並符合針對Animator提供的動畫型態。Android系統提供一組普通的Interpolator都放在android.view.animation package,如果這些無法滿足需求,你可以實現TimeInterpolator介面建立自己的。

舉例,預設的AccelerateDecelerateInterpolator及LinearInterpolator如何計算interpolated分數值得比較如下。


AccelerateDecelerateInterpolator
public float getInterpolation(float input) {
    return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}
LinearInterpolator
public float getInterpolation(float input) {
    return input;
}

下表顯示一個動畫由這些interpolators計算的大約數值。


ms elapsedElapsed fraction/Interpolated fraction (Linear)Interpolated fraction (Accelerate/Decelerate)
000
200.2.1
400.4.345
600.6.8
800.8.9
100011

如表顯示,LinearInterpolator以等速改變數值,每200毫秒改變0.2;AccelerateDeccelerateInterpolator在200毫秒到600毫秒間改變數值的速度比LinearInterpolator快,在600毫秒到1000毫秒間比LinearInterpolator慢。


星期二, 1月 24, 2012

Animation (六)

Android應用程式學習筆記

Animation Listeners

你可以在動畫期間用以下描述的監聽器監聽重要事件。

  • Animator.AnimatorListener
    • onAinmationStart()-當動畫開始時呼叫。
    • onAnimationEnd()-當動畫停止時呼叫。
    • onAnimationRepeat()-當動畫重複時呼叫。
    • onAnimationCancel()-當動畫被取消掉時呼叫,被取消的動畫也會呼叫onAnimationEnd()方法。
  • ValueAnimator.AnimatorUpdateListener
    • onAnimationUpdate()-動畫中的每個frame都會呼叫。監聽此事件來利用動畫過程中由ValueAnimator產生的數據。getAnimtedValue()方法查詢傳入事件的ValueAnimtor物件取得目前的動畫值,如果你使用ValueAnimator必須實現此監聽器。
    • 根據你動畫的屬性或是物件,你也許需要在一個視圖上呼叫invalidate()方法,強制用新的動畫值重新繪製屏幕。
如果你不想實現Animator.AnimatorListener介面的所有方法,可以繼承AnimatorListenerAdapter被類別取代實現Animator.AnimatorListener介面。AnimatorListenerAdapter提供空的方法,你可以選擇性地複寫。

舉例

ValueAnimatorAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
    balls.remove(((ObjectAnimator)animation).getTarget());
}


Animating Layout Changes to ViewGroups

屬性動畫系統提供一個功能讓動畫的變化變成一個ViewGroup物件,提供了一個對視圖物件動畫的更簡易方法。

你可以用LayoutTransition類別將動畫布局改變成ViewGroup,ViewGroup中的視圖可以透過當你從ViewGroup增加或移除視圖或是當你呼叫視圖的setVisibility()方法設定VISIBLE或GONE來顯現或不顯現動畫,當你新增或移除視圖時,在ViewGroup中的其餘視圖也可以動畫到它們新的位置。你可以藉由呼叫setAnimator在LayoutTransition物件中定義動畫且傳遞以下其中一個LayoutTransition常數到Animator物件。

  • APPEARING - 表示運行在動畫上的項目顯示在容器中的標籤。
  • CHNAGE_APPEARING - 表示運行在動畫上的項目由於容器中新的項目顯現而改變的標籤。
  • DISAPPEARING - 表示運行在動畫中的項目從容器中消失的標籤。
  • CHANGE_DISAPPEARING - 表示運行在動畫中的項目由於一個項目從容器中消失而改變的標籤。
你可以自己為這四種事件型態自定義動畫來客製化布局transition的外觀或只是告訴動畫系統使用預設的動畫。

在API Demos中有LayoutAnimation的範例,為你演示如何為layout transition定義動畫,接著設定動畫到你想動畫的視圖上。

LayoutAnimationByDefault及它對應的layout_animations_by_default.xml布局資源文件為你演示如何將預設的layout transition轉成XML,你需要做的唯一一件事就是為ViewGroup設定android:animationLayoutchanges屬性為true,舉例:

<LinearLayout
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="@+id/verticalContainer"
    android:animateLayoutChanges="true" />

星期日, 1月 22, 2012

Animation (五)

Android應用程式學習筆記

Animating with ValueAnimator

ValueAnimator類別讓你藉由指定一組整數、浮點數、顏色的動畫數值來定義一些型態的動畫,你可以呼叫其中的方法ofInt()、offloat()、ofobject()獲得一個ValueAnimator。例如:


ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.start();

在此程式碼中,當start()方法運行,ValueAnimator開始計算動畫數值,數值介於0與1之間,動畫時間1000豪秒。

你也可以指定自定義的動畫:


ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();

在此程式碼中,當start()方法運行,ValueAnimator開始計算動畫數值,數值介於startPropertyValue與endPropertyValue之間提供MyTypeEvaluator物件使用,動畫時間1000毫秒。

前一程式碼片段沒有實際效果,因為ValueAnimator沒有直接地操作物件或屬性。你想做的最有可能的事情是改變物件讓它依你想動畫的計算數值。你可以為ValueAnimator定義適合的監聽器處理在動畫期間重要的事件,例如框架更新。當執行監聽器,你可以呼叫getAnimatorValue()方法獲得計算指定框架更新的數值,在Animation Listener文章中獲得更多監聽器的資訊。


Animating with ObjectAnimator

ObjectAnimator是ValueAnimator的子類並結合時序引擎及ValueAnimator的數值計算,利用這些功能完成目標物件的動畫。ObjectAnimator較輕易對任何物件完成動畫,你不再需要實現ValueAnimator.AnimatorUpdateListener,因為動畫屬性會自動更新。

實作一個ObjectAnimator與實作VlaueAnimator相似,但是你也可以隨著動畫指定數值給物件及物件屬性名稱。


ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);
anim.setDuration(1000);
anim.start();

正確地更新ObjectAnimator,你必須照著以下去做:

  • 你正在動畫的物件屬性必須有一個格式為set<propertyName>()的setter函式,因為ObjectAnimator會在動畫期間自動地更新屬性,它必須能夠用setter函式存取屬性。舉例,如果屬性名稱為foo,你需要一個setfoo()的方法。如果這個setter方法不存在,你有三種選擇:
    • 如果你有權力如此做,你就在類別中加入一個setter方法。
    • 利用包裝類別讓你有權力改變並有包裝類接收來自有效的設定方法的數值,並發送到原本的物件。
    • 用ValueAnimator代替。
  • 如果你只能在一個ObjectAnimator工廠方法指定一個values...參數的數值,它被假定為動畫結束的數值。因此你動畫的物件屬性必須有一個getter方法,用來獲得動畫一開始的數值。這個getter方法必須是get<propertyNmae>()格式。比如,你有一個屬性名稱為foo,你必須有一個getfoo()方法。
  • 你正在動畫的屬性的getter與setter方法必須運轉在相同型態,作為指定給ObjectAnimator的起始與結束值。例如,如果你建立以下的ObjectAnimator,必須有targetObject.setPropName(float)及targetObject.getPropName(float)。
  • ObjectAnimator.ofFloat(targetObject, "propName", 1f)
  • 根據你動畫的物件或是屬性,你可能需要在一個視圖用更新的動畫數值強制在屏幕上重繪時呼叫invalidate()方法,你在onAnimateUpdate()回呼方法中如此做。例如,動畫Drawable物件的顏色屬性只會導致當物件重繪時更新到屏幕,所有視圖的屬性setter,比如setAlpha()方法及setTranslationX()方法適當地廢止視圖,所以你不需要當用新的數值呼叫這些方法去廢止視圖。更多有關監聽器的資訊,會在Animation listener文章中說明。

Animation (四)

Android 應用程式學筆記

API Overview

你可以在android.animation中找到大部分的屬性動畫系統,因為在andorid.view.animation中已定義了許多interpolator了,你可以在屬性動畫系統使用這些interpolator,以下表格描述了屬性動畫系統主要的組件。

Animator類別提供建立動畫的基礎架構。正常來說你不需要直接使用到animator類別,它只提供延伸支持全部的動畫的最小的功能。以下為繼承自animator的類別。


Table 1. Animators
ClassDescription
ValueAnimatorThe main timing engine for property animation that also computes the values for the property to be animated. It has all of the core functionality that calculates animation values and contains the timing details of each animation, information about whether an animation repeats, listeners that receive update events, and the ability to set custom types to evaluate. There are two pieces to animating properties: calculating the animated values and setting those values on the object and property that is being animated. ValueAnimator does not carry out the second piece, so you must listen for updates to values calculated by the ValueAnimator and modify the objects that you want to animate with your own logic. See the section about Animating with ValueAnimator for more information.
ObjectAnimatorA subclass of ValueAnimator that allows you to set a target object and object property to animate. This class updates the property accordingly when it computes a new value for the animation. You want to use ObjectAnimator most of the time, because it makes the process of animating values on target objects much easier. However, you sometimes want to use ValueAnimator directly because ObjectAnimator has a few more restrictions, such as requiring specific acessor methods to be present on the target object.
AnimatorSetProvides a mechanism to group animations together so that they run in relation to one another. You can set animations to play together, sequentially, or after a specified delay. See the section about Choreographing multiple animations with Animator Sets for more information.

Evaluator告訴屬性動畫系統如何計算屬性的數值,它們用Animator類別提供的時序的資料,動畫起始和結束的數值,並根據這些數據計算動畫的屬性數值。以下為屬性動畫系統的evaluator。


Table 2. Evaluators
Class/InterfaceDescription
IntEvaluatorThe default evaluator to calculate values for int properties.
FloatEvaluatorThe default evaluator to calculate values for float properties.
ArgbEvaluatorThe default evaluator to calculate values for color properties that are represented as hexidecimal values.
TypeEvaluatorAn interface that allows you to create your own evaluator. If you are animating an object property that is not an intfloat, or color, you must implement the TypeEvaluator interface to specify how to compute the object property's animated values. You can also specify a customTypeEvaluator for intfloat, and color values as well, if you want to process those types differently than the default behavior. See the section about Using a TypeEvaluator for more information on how to write a custom evaluator.


TimeInterpolator定義如何在動畫中的數值作為工的能時序,例如,你可以指定整個動畫為線性,或者你可以動畫為非線性的,例如,在動畫開始為加速,動畫結束時減速。表三顯示在android.view.animation中的interpolator。如果沒有合適你需要的interpolator,你可以實現TimeInterpolator介面和創建你自己的。你可以在Using interpolators文章中了解更多資訊與如何自定義interpolator。


Table 3. Interpolators
Class/InterfaceDescription
AccelerateDecelerateInterpolatorAn interpolator whose rate of change starts and ends slowly but accelerates through the middle.
AccelerateInterpolatorAn interpolator whose rate of change starts out slowly and then accelerates.
AnticipateInterpolatorAn interpolator whose change starts backward then flings forward.
AnticipateOvershootInterpolatorAn interpolator whose change starts backward, flings forward and overshoots the target value, then finally goes back to the final value.
BounceInterpolatorAn interpolator whose change bounces at the end.
CycleInterpolatorAn interpolator whose animation repeats for a specified number of cycles.
DecelerateInterpolatorAn interpolator whose rate of change starts out quickly and and then decelerates.
LinearInterpolatorAn interpolator whose rate of change is constant.
OvershootInterpolatorAn interpolator whose change flings forward and overshoots the last value then comes back.
TimeInterpolatorAn interface that allows you to implement your own interpolator.