Xamarin:Android:Animator 控制器簡單使用法

原文說明:看這裡

這篇主要介紹 Property animators 的常見用法,使用前要引用下面的 Name Space
using Android.Animation

這個 animators 有三個子類別

ValueAnimator - 數值計數器,數字更新對象必須以加載是件方式執行
ObjectAnimator - 進階版 ValueAnimator 可以直接指定物件與更新對象
AnimatorSet - 動作集合器,可以把許多 ValueAnimator 和 ObjectAnimator 掛載一起執行,也可以指定執行順序

ValueAnimator
其實這個 ValueAnimator 控制器,說穿了就是一個線性計數器而已,跟繪圖一點關係都沒有,因為它的基本動作就是:

你給予 A 到 B 區間的數字,然後要它在一定時間內跑完,然後在跑數字的時候同時去更新某個變數。

下面有個基本範例,這個範例可以讓顯示的文字從0漸增到100,然後再從100漸減到0,每次的變化需要的時間剛好就1秒:


//設定數字 0 到100 的變化
ValueAnimator valueAnimator = ValueAnimator.ofInt(0 , 100);
//並且在 1000毫秒內執行完
valueAnimator.SetDuration(1000);
//設定為無限次執行
valueAnimator.RepeatCount = ValueAnimator.Infinite;
//循環方式為『反向計數』
valueAnimator.RepeatMode = ValueAnimatorRepeatMode.Reverse;

//當數字發生變化時,更新TextView的文字顯示
valueAnimator.Update += delegate (object sender,ValueAnimator.AnimatorUpdateEventArgs e)
{
        //取得變化數值
        var newValue = (int)e.Animation.AnimatedValue;
        var tv1 = FindViewById<TextView>(Resource.Id.textView1);
        tv1.Text = newValue.ToString();
}

//啟動 animator
valueAnimator.Start();


ObjectAnimator
如果不想使用『事件』去更新對象,可以使用 ObjectAnimator 直接指定要更新的對象物件與變數,這是針對比較單純的目的去處理。

底下範例效果同上面的程式碼:


//對MyTextView的MeMe屬性設定數字 0 到100 的變化
var tv2 = FindViewById<MyTextView>(Resource.Id.textView2);
ObjectAnimator objectAnimator = ObjectAnimator.OfInt(tv2, "MeMe", 1, 100);
objectAnimator.SetDuration(1000);
objectAnimator.RepeatCount = ObjectAnimator.Infinite;
//底下因為沒有ObjectAnimatorRepeatMode這種列舉,所以直接使用ValueAnimatorRepeatMode
objectAnimator.RepeatMode = ValueAnimatorRepeatMode.Restart;
//啟動 animator
objectAnimator.Start();


AnimatorSet
這是個可以把一堆 ValueAnimator 和 ObjectAnimator 整合在一起執行的動作集合器
我們可以用以下的範例讓兩個 TextView的文字 交互執行遞增和遞減的動作

先建立 activity 層級變數, 因為在底下做 ObjectAnimation 參考的 tv4 變數會因為 離開onCreate而被消滅,導至無法執行。


public class MainActivity : Activity
    {
        public MyTextView  tv4 = FindViewById<MyTextView>(Resource.Id.textView4);
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
                        .
                        .
                        .



//建立一個升值 ValueAnimator
ValueAnimator vUpAnimator = ValueAnimator.OfInt(1, 100);
vUpAnimator.SetDuration(1000);
vUpAnimator.Update += delegate (object sender, ValueAnimator.AnimatorUpdateEventArgs e)
{
        //設定更新對象
        var newValue = (int)e.Animation.AnimatedValue;
        var tv3 = FindViewById<TextView>(Resource.Id.textView3);
        tv3.Text = newValue.ToString();
};
//建立一個降值 ValueAnimator
ValueAnimator vDnAnimation = ValueAnimator.OfInt(100, 1);
vDnAnimation.SetDuration(1000);
vDnAnimation.Update += delegate (object sender, ValueAnimator.AnimatorUpdateEventArgs e)
{
        //設定更新對象
        var newValue = (int)e.Animation.AnimatedValue;
        var tv3 = FindViewById<TextView>(Resource.Id.textView3);
        tv3.Text = newValue.ToString();
};
//建立一個升值 ObjectAnimator
ObjectAnimator oUptAnimator = ObjectAnimator.OfInt(tv4, "MeMe", 1, 100);
oUptAnimator.SetDuration(1000);
//建立一個降值 ValueAnimator
ObjectAnimator oDntAnimator = ObjectAnimator.OfInt(tv4, "MeMe", 100, 1);
oDntAnimator.SetDuration(1000);

//建立一個動作整合器
AnimatorSet animatorSet = new AnimatorSet();
//設定動作順序
animatorSet.PlaySequentially(vUpAnimator, oUptAnimator, vDnAnimation, oDntAnimator);
//啟動動作整合器
animatorSet.Start();



重複的 AnimatorSet :
因為 AnimatorSet 沒有 RepeatCount 屬性,所以必須自己處理,處理方式不難,就是利用 AnimatorSet 結束時的事件通知,再讓 AnimatorSet 執行即可。


//獲取 AnimatorSet 結束事件
animatorSet.AnimationEnd += delegate
{
        animatorSet.Start();
}


如果想執行指定的次數,只要在 AnimationEnd 事件內弄個共享變數加個判斷即可。

其他注意事項:
1.當使用 animatorSet 的循序執行 PlaySequentially 去執行 ValueAnimator /ObjectAnimator (以下通稱 animator) 時 ,animator 的 RepeatCount 不可以設定為 Infinite 狀態,否則在指令內遇到 Infinite 的 animator 後,下一個 animator 動作就永遠不會被執行了。
2. animator 也可以執行浮點 ofFloat 、顏色 ofArgb 與物件 ofObject 的計數執行。
3. AnimatorSet 除了循序執行 PlaySequentially 也有同時執行 PlayTogether ,在這個同時執行模式下就不必擔心 animator 設定為 Infinite 執行狀態,因為不會互相干擾。
4.範例中用的 MyTextView 是繼承型的自訂 TextView,所以才有 MeMe 屬性。

Animator 這個類別命名很容易讓人以為是做為『動畫』的,但實際上畫面不是它的主要操作對象,反而比較像動畫中的『時間』與『方向』元素的操作,不過確實有了它支援,不同時間屬性與方向性的動畫物件才得以容易實現。




留言

這個網誌中的熱門文章

【研究】列印的條碼為什麼很難刷(掃描)

C# 使用 Process.Start 執行外部程式

統一發票列印小程式