學習目標
- Animation - RotateTo, ScaleTo, Translateto, FadeTo, LayoutTo
- 第二次點擊失效原因與解法
- Easing Function - 動畫曲線
Xamarin.Forms 對物件的形狀位置變化,除了像上一章節手動更改物件的屬性,來放大縮小移動位置。
同時也提供了一些簡易的 動畫方法,如漸漸消失,移動到某處,變大,旋轉..
動畫方法目前不支援寫在 XAML,全部都要用 C#
XAML 內只有一顆按鈕:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="AnimationTryout.AnimationTryoutPage"> <Button x:Name="button" Text="Tap Me!" FontSize="Large" HorizontalOptions="Center" VerticalOptions="Center" Clicked="OnButtonClicked" /> </ContentPage>.cs
讓按鈕旋轉 360 度:
public partial class AnimationTryoutPage : ContentPage { public AnimationTryoutPage() { InitializeComponent(); } void OnButtonClicked(object sender, EventArgs args) { button.RotateTo(360); } }
RotateTo 方法就是一個讓物件可以旋轉的動畫方法
當旋轉完,要按下第二次時會發現不轉了!!! 怎麼了你累了...?
是因為,我們第一次讓按鈕 從 0 轉到 360 後,其值會保持在 360,
所以第二次按下去時,程式會要求按鈕 從 360 轉到 360 ,如此一來就沒有反應
遇到第二次不能的問題,可以改用 RelRotateTo() 這方法,
這方法會在每次動畫結束時,重新設定其物件參數值 ( Rotation 回到 0 )
總之,第二次執行復活
當然也可以在每次執行動畫前手動初始化:
void OnButtonClicked(object sender, EventArgs args) { button.Rotation = 0; button.RotateTo(360, 2000); }
void OnButtonClicked(object sender, EventArgs args) { //提高到 2000 毫秒內轉完,一般預設是 250 毫秒 button.RotateTo(360, 2000); }
連續動畫
由於動畫方法是屬於 非同步方法,故能加上 await ,讓每一動畫去等待上一動畫結束。
async void OnButtonClicked(object sender, EventArgs args) { await button.RotateTo(90, 250); await button.RotateTo(-90, 500); await button.RotateTo(0, 250); }
合併動畫
除了 RotateTo 外, Xamarin.Forms 還提供了 ScaleTo、TranslateTo、FadeTo 和 LayoutTo 等動畫方法可以使用。
假設我們現在要將兩個動畫混合在一起,例如 旋轉同時也要放大縮小
可以使用 Task 提供的兩個方法來處理,Task.WhenAll 和 Task.WhenAny,
這兩個方法能夠放入數個非同步方法並一起執行
Task.WhenAll
等全部非同步方法執行完才離開
Task.WhenAny
當有任一個非同步方法執行完畢就會離開
上範例:
async void OnButtonClicked(object sender, EventArgs args) { button.Rotation = 0; //當放大結束時就會去執行縮小 await Task.WhenAny( button.RotateTo(360, 2000), button.ScaleTo(5, 1000) ); await button.ScaleTo(1, 1000); }
* 註1:
做 RotateTo 和 ScaleTo 時,
可以設定 錨定點( AnchorX & AnchorY ) 屬性 ,去釘住物件要旋轉或放大的固定位置
* 註2:
如果我們要取消動畫,可以用這個方法:
ViewExtensions.CancelAnimations(button);
Easing Function - 動畫曲線
async void OnButtonClicked(object sender, EventArgs args) { await button.RotateTo(90, 250); await button.RotateTo(-90, 500); await button.RotateTo(0, 250); }
如果你有執行以上程式,會覺得其動作相當生硬且機械感十足...
為此,Xamarin.Forms 很貼心的提供了好幾組動畫曲線,加上去後可以讓動畫看起來很圓滑或是活潑...
試試看以下程式,將 Easing function 加入動畫:
async void OnButtonClicked(object sender, EventArgs args) { await button.RotateTo(90, 250, Easing.SinOut); await button.RotateTo(-90, 500, Easing.SinInOut); await button.RotateTo(0, 250, Easing.SinIn); }
眼睛好的會發現動作較圓滑了...
Easing function 全部有五個類別:
- Linear - 預設
- SinIn, SinOut, and SinInOut
- CubicIn, CubicOut, and CubicInOut
- BounceIn and BounceOut
- SpringIn and SpringOut
原文書提供執行時的曲線,但說真的,乍看下不知道這些圖在衝殺虫…
搭配動畫來看會更清楚,以下都用旋轉來做範例
反差大系列 - CubicIn, CubicOut, and CubicInOut
彈跳系列 - BounceIn, BounceOut
倒退嚕系列 - SpringIn, SpringOut
LayoutTo
最後要提一下最奇特動畫方法,因為要傳入的參數居然是 Rectangle
通常在 AbsoluteLayout 使用,並將含有 x, y , width, height 四個數值的 Rectangle 傳入,直接控制物件要做變化的四個屬性。
我們不會在 StackLayout 或 Grid 使用 LayoutTo,因為以上兩個容器都會自動排版或調整子元素的位置。
你是我见过唯一一个写教程这么详细和用心的人,你的态度值得尊敬。小弟佩服。也希望罗大神以后在Xamarin方面能多多指教。先谢谢了
回覆刪除感謝支持,每篇文章都花了許多時間去閱讀原文教學,翻譯,編排和修改,好好珍惜就好哈哈。當然也是希望能用中文推廣這項技術
刪除