Xamarin : android : Animation 特效 - 按鈕動畫測試

如果版面上需要讓 View (控件) 有點特效,其實 android 有提供一些基本2D的特效可以使用,這個就是 Animation。
※先說明Animation在這裡是一種效果,並非我們認知的那種動畫,所以無法設計太多一連串的動作,因此通常比較適合『咻一下子』這種感覺。

1 . 要在要運行的 Activity 引入

Using Android.Views.Animations

2 . 然後在右邊Resource資料夾下建立一個anim資料夾(這個請勿隨意命名,因為在android套件是有關聯的,隨意命名會找不到)



3 . 然後在anim資料夾下建立你的預訂好的動畫(特效)檔案,它基本上就是一個XML檔案。


這個檔案的詳細內容寫法可以參考下面網站:
官方網站(詳細但太多太雜,很容易找不到重點):https://developer.xamarin.com/guides/android/application_fundamentals/graphics_and_animation/
極客學院(簡單易懂,但無太多詳細解釋):http://wiki.jikexueyuan.com/project/android-animation/1.html



我這邊準備了幾個特效檔案:
breath.xml (呼吸效果)


<?xml version="1.0" encoding="utf-8" ?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
       android:fromAlpha="1.0"
       android:toAlpha="0.3"
       android:duration="500"
       android:fillBefore ="true"
       android:repeatCount="10"
       android:repeatMode="reverse"
/>


fadeinout.xml (淡入淡出)


<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillBefore ="true">
  <alpha
    android:fromAlpha="1.0"
    android:toAlpha="0.7"
    android:duration="100" />
  <alpha
    android:fromAlpha="0.7"
    android:toAlpha ="1.0"
    android:duration="100"
    android:startOffset="100" />
</set>


fadescalecombine.xml (組合淡入出+縮小放大)


<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillBefore ="true">
  <scale
    android:fromXScale="1.0"
    android:toXScale="0.95"
    android:fromYScale="1.0"
    android:toYScale="0.95"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="100" />
  <alpha
   android:fromAlpha="1.0"
   android:toAlpha="0.5"
   android:duration="100" />
  <scale
    android:fromXScale="0.95"
    android:toXScale ="1.0"
    android:fromYScale="0.95"
    android:toYScale ="1.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="100"
    android:startOffset="100" />
  <alpha
    android:fromAlpha="0.5"
    android:toAlpha ="1.0"
    android:duration="100"
    android:startOffset="100" />
</set>


hartattack.xml (心臟病)


<?xml version="1.0" encoding="utf-8" ?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
       android:fromXScale="1.0"
       android:toXScale="0.85"
       android:fromYScale="1.0"
       android:toYScale="0.85"
       android:pivotX="50%"
       android:pivotY="50%"
       android:duration="100"
       android:fillBefore ="true"
       android:repeatCount="10"
/>


rotate.xml (旋轉)


<?xml version="1.0" encoding="utf-8" ?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:fromDegrees="0"
        android:toDegrees="1080"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="700"
        android:fillAfter="true"
        android:repeatMode="reverse"
        android:fillBefore ="true"
        android:repeatCount="1"
/>


rotatejump.xml (一邊旋轉一邊縮小)


<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillBefore ="true">
  <scale
    android:fromXScale="1.0"
    android:toXScale="0.4"
    android:fromYScale="1.0"
    android:toYScale="5"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="200" />
  <rotate
    android:fromDegrees="0"
    android:toDegrees="720"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="700"
    android:startOffset="200"/>
  <scale
    android:fromXScale="1.5"
    android:toXScale="0.3"
    android:fromYScale="1.5"
    android:toYScale="0.3"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="700"
    android:startOffset="200"/>
  <scale
    android:fromXScale="0.5"
    android:toXScale="1.0"
    android:fromYScale="0.5"
    android:toYScale="1.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="100"
    android:startOffset="900" />
</set>


scaleinout.xml (縮小放大)


<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillBefore ="true">
  <scale
    android:fromXScale="1.0"
    android:toXScale="0.95"
    android:fromYScale="1.0"
    android:toYScale="0.95"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="100" />
  <scale
    android:fromXScale="0.95"
    android:toXScale ="1.0"
    android:fromYScale="0.95"
    android:toYScale ="1.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="100"
    android:startOffset="100" />
</set>


shake.xml (左右振動)


<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillBefore ="true">
  <scale
    android:fromXScale="1.0"
    android:toXScale="0.99"
    android:fromYScale="1.0"
    android:toYScale="1.0"
    android:pivotX="50%"
    android:pivotY="100%"
    android:duration="100" />
  <translate
   android:fromXDelta="0"
   android:toXDelta="-10"
   android:duration="50"
   android:startOffset="100" />
  <translate
   android:fromXDelta="-10"
   android:toXDelta="10"
   android:duration="100"
   android:startOffset="150" />
  <translate
   android:fromXDelta="10"
   android:toXDelta="-10"
   android:duration="100"
   android:startOffset="250" />
  <translate
   android:fromXDelta="-10"
   android:toXDelta="10"
   android:duration="100"
   android:startOffset="350" />
  <translate
   android:fromXDelta="10"
   android:toXDelta="-10"
   android:duration="100"
   android:startOffset="450" />
  <translate
   android:fromXDelta="-10"
   android:toXDelta="0"
   android:duration="50"
   android:startOffset="550" />
</set>


4 .建立 Main.axml
 這個很簡單,就是拉幾個 Button到畫面上而已


5 .在按鈕 Click 事件中建立 Animation 物件,並讓控件 Button 執行 startAnimation


var btn1 = FindViewById<Button>(Resource.Id.button1);
btn1.Click += delegate
{
    //取得載入動畫資源檔(組合淡化&大小)
    Animation animation = AnimationUtils.LoadAnimation(Application.Context, Resource.Animation.fadescalecombine);
    btn1.StartAnimation(animation);
};
var btn2 = FindViewById<Button>(Resource.Id.button2);
btn2.Click += delegate
{
    //取得載入動畫資源檔(大小)
    Animation animation = AnimationUtils.LoadAnimation(Application.Context, Resource.Animation.scaleinout);
    btn2.StartAnimation(animation);
};
var btn3 = FindViewById<Button>(Resource.Id.button3);
btn3.Click += delegate
{
    //取得載入動畫資源檔(淡化)
    Animation animation = AnimationUtils.LoadAnimation(Application.Context, Resource.Animation.fadeinout);
    btn3.StartAnimation(animation);
};


當然你可以在外層定義並產生好特效物件,然後讓需要使用的控件(View),只是執行相同動畫,共同使用這個 animation 特效的 View 會以相同速率與模式一起運作,感覺好像是同步一般。


namespace BtnClickEfct
{
    [Activity(Label = "BtnClickEfct", MainLauncher = true)]
    public class MainActivity : Activity
    {
        //動畫資源設定在共享外層
        Animation animation;
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);
         
            //取得載入動畫資源檔,建立一次大家共用
            animation = AnimationUtils.LoadAnimation(Application.Context, Resource.Animation.fadescalecombine);
         
            //針對要使用的對象加入
            var btn1 = FindViewById<Button>(Resource.Id.button1);
            btn1.Click += delegate
            {
               btn1.StartAnimation(animation);
            };
            var btn2 = FindViewById<Button>(Resource.Id.button2);
            btn2.Click += delegate
            {
               btn2.StartAnimation(animation);
            };


注意到 Resource.Animation 這個資源了嗎?它就是對應 anim 資料夾,所以前面才會說資料夾名稱不可以亂改。

Resource.Animation.fadescalecombine 後面 fadescalecombine 看得出來很明顯就是我們的XML檔案了

6 . 如果希望停止 Animation 可以用:


animation.Cancle();


這個指令執行比較像『暫停』,被控制的對象狀態會停止在被 Cancle 的那一刻。
但是要小心,如果許多控制物件共用這個動畫資源,可能會導致大家一起停止。
優點是可以再用一次 下面指令再次啟動:


animation.Start();


這樣感覺有點怪。

不喜歡的話,也可以使用:


btn1.ClearAnimation();


對該控制物件清除動畫設定,控制物件視覺會恢復到原本樣貌。
但如果要再次啟動該控制物件的動畫,就必須再設定一次:


btn1.StartAnimation(animation);






留言

這個網誌中的熱門文章

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

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

統一發票列印小程式