共用方式為


中的簡單動畫 Xamarin.Forms

ViewExtensions 類別提供可用來建構簡單動畫的擴充方法。 本文示範如何使用 ViewExtensions 類別建立和取消動畫。

類別 ViewExtensions 提供下列擴充方法,可用來建立簡單的動畫:

根據預設,每個動畫將需要 250 毫秒。 不過,建立動畫時可以指定每個動畫的持續時間。

注意

類別 ViewExtensions 提供 LayoutTo 擴充方法。 不過,這個方法供版面配置用來以動畫顯示包含大小和位置變更的配置狀態之間的轉換。 因此,它應該只供 Layout 子類別使用。

類別中的 ViewExtensions 動畫擴充方法都是異步的,並傳 Task<bool> 回 物件。 如果動畫完成,而且true動畫已取消,則傳回值false為 。 因此,動畫方法通常應該與運算符搭配 await 使用,這可讓您輕鬆地判斷動畫何時完成。 此外,接著,在上一個方法完成之後,就可以使用後續的動畫方法建立循序動畫。 如需詳細資訊,請參閱 復合動畫

如果需要讓動畫在背景中完成, await 則可以省略 運算符。 在此案例中,動畫擴充方法會在起始動畫之後快速傳回,且動畫發生在背景中。 建立復合動畫時,可以利用這項作業。 如需詳細資訊,請參閱 復合動畫

如需運算子的詳細資訊 await ,請參閱 異步支援概觀

單一動畫

中的每個 ViewExtensions 擴充方法都會實作單一動畫作業,該作業會在一段時間內逐漸將屬性從一個值變更為另一個值。 本節會探索每個動畫作業。

輪替

下列程式代碼範例示範如何使用 RotateTo 方法來建立 Rotation 屬性的 Image動畫效果:

await image.RotateTo (360, 2000);
image.Rotation = 0;

此程式代碼會透過在2秒 (2000 毫秒) 內旋轉高達360度,以動畫顯示 Image 實例。 方法 RotateTo 會取得動畫開頭的目前 Rotation 屬性值,然後從該值旋轉至第一個自變數 (360)。 動畫完成之後,影像的 Rotation 屬性會重設為 0。 這可確保 Rotation 在動畫結束之後,屬性不會維持在 360,這樣會防止其他旋轉。

下列螢幕快照顯示每個平臺上的輪替進行中:

旋轉動畫

注意

除了 RotateTo 方法之外,還有和 RotateXToRotateYTo 方法分別以動畫顯示 RotationXRotationY 屬性。

相對旋轉

下列程式代碼範例示範如何使用 RelRotateTo 方法來累加增加或減少 RotationImage屬性:

await image.RelRotateTo (360, 2000);

此程式代碼會從實例的起始位置旋轉 360 度,超過 2 秒(2000 毫秒)來產生動畫 Image 效果。 方法 RelRotateTo 會取得動畫開頭的目前 Rotation 屬性值,然後從該值旋轉至值加上其第一個自變數 (360)。 這可確保每個動畫一律會從起始位置旋轉 360 度。 因此,如果在動畫進行中時叫用新的動畫,它會從目前的位置開始,而且可能以非遞增 360 度的位置結束。

下列螢幕快照顯示每個平臺上的相對輪替:

相對旋轉動畫

調整大小

下列程式代碼範例示範如何使用 ScaleTo 方法來建立 Scale 屬性的 Image動畫效果:

await image.ScaleTo (2, 2000);

此程式代碼會將實例的大小相應增加至 2 秒 (2000 毫秒) 的兩倍,以產生動畫 Image 效果。 方法 ScaleTo 會取得動畫開頭的目前 Scale 屬性值 (預設值 1),然後從該值調整為第一個自變數 (2)。 這會影響將影像大小擴充為其大小兩倍的效果。

下列螢幕快照顯示每個平臺上的調整進行中:

調整動畫

注意

除了 ScaleTo 方法之外,還有和 ScaleXToScaleYTo 方法分別以動畫顯示 ScaleXScaleY 屬性。

相對調整

下列程式代碼範例示範如何使用 RelScaleTo 方法來建立 Scale 屬性的 Image動畫效果:

await image.RelScaleTo (2, 2000);

此程式代碼會將實例的大小相應增加至 2 秒 (2000 毫秒) 的兩倍,以產生動畫 Image 效果。 方法 RelScaleTo 會取得動畫開頭的目前 Scale 屬性值,然後從該值調整為值加上第一個自變數 (2)。 這可確保每個動畫一律會從起始位置調整為 2。

使用錨點調整和旋轉

AnchorXAnchorY 屬性會設定 和 Scale 屬性的Rotation縮放或旋轉中心。 因此,其值也會影響 RotateToScaleTo 方法。

Image假設已放置在版面配置中央的 ,下列程式代碼範例會藉由設定其 AnchorY 屬性,示範在版面配置中央旋轉影像:

double radius = Math.Min(absoluteLayout.Width, absoluteLayout.Height) / 2;
image.AnchorY = radius / image.Height;
await image.RotateTo(360, 2000);

若要繞 Image 版面配置中心旋轉實例,和 AnchorXAnchorY 屬性必須設定為相對於 寬度和高度 Image的值。 在此範例中,會將的中心 Image 定義為配置的中心,因此預設值 AnchorX 0.5 不需要變更。 不過,屬性 AnchorY 會重新定義為從 頂端 Image 到版面配置中心點的值。 這可確保 Image 在版面配置中心點周圍進行 360 度的完整旋轉,如下列螢幕快照所示:

使用錨點旋轉動畫

翻譯

下列程式代碼範例示範如何使用 TranslateTo 方法來建立 TranslationXTranslationY 屬性的 Image動畫效果:

await image.TranslateTo (-100, -100, 1000);

此程式代碼會透過水準和垂直轉譯超過1秒(1000毫秒)來產生實例的動畫 Image 效果。 方法 TranslateTo 會同時將影像向左轉譯 100 像素,向上轉譯 100 圖元。 這是因為第一個和第二個自變數都是負數。 提供正數會將影像轉譯為右側和向下。

下列螢幕快照顯示每個平臺上的翻譯進行中:

翻譯動畫

注意

如果元素一開始已配置螢幕,然後轉譯到畫面上,則在翻譯元素的輸入配置維持在畫面外,且使用者無法與其互動。 因此,建議將檢視配置在其最終位置,然後執行任何必要的翻譯。

淡出

下列程式代碼範例示範如何使用 FadeTo 方法來建立 Opacity 屬性的 Image動畫效果:

image.Opacity = 0;
await image.FadeTo (1, 4000);

此程式代碼會在 4 秒(4000 毫秒)內淡化實例,以動畫 Image 顯示實例。 方法 FadeTo 會取得動畫開頭的目前 Opacity 屬性值,然後從該值淡入到第一個自變數 (1)。

下列螢幕快照顯示每個平臺上的淡入進度:

淡化動畫

復合動畫

復合動畫是動畫的循序組合,可以使用 運算子建立 await ,如下列程式代碼範例所示:

await image.TranslateTo (-100, 0, 1000);    // Move image left
await image.TranslateTo (-100, -100, 1000); // Move image diagonally up and left
await image.TranslateTo (100, 100, 2000);   // Move image diagonally down and right
await image.TranslateTo (0, 100, 1000);     // Move image left
await image.TranslateTo (0, 0, 1000);       // Move image up

在此範例中, Image 會轉譯超過 6 秒(6000 毫秒)。 的 Image 轉譯會使用五個動畫,而 await 運算元表示每個動畫會循序執行。 因此,後續動畫方法會在上一個方法完成之後執行。

復合動畫

復合動畫是動畫的組合,其中兩個或多個動畫會同時執行。 復合動畫可以混合等候和非等候的動畫來建立,如下列程式代碼範例所示:

image.RotateTo (360, 4000);
await image.ScaleTo (2, 2000);
await image.ScaleTo (1, 2000);

在此範例中, Image 會縮放並同時旋轉超過 4 秒(4000 毫秒)。 的縮放 Image 比例會使用與旋轉同時發生的兩個循序動畫。 RotateTo方法會在沒有運算符的情況下執行,並立即傳回 ,然後開始第一個awaitScaleTo動畫。 第 await 一個 ScaleTo 方法呼叫上的運算符會延遲第二 ScaleTo 個方法呼叫,直到第一個 ScaleTo 方法呼叫完成為止。 此時動畫 RotateTo 已完成一半, Image 並將旋轉 180 度。 在最後 2 秒(2000 毫秒)期間,第二 ScaleTo 個動畫和 RotateTo 動畫都已完成。

同時執行多個異步方法

staticTask.WhenAnyTask.WhenAll 方法可用來同時執行多個異步方法,因此可用來建立復合動畫。 這兩種方法 Task 都會傳回 物件,並接受每一個傳回 Task 物件的方法集合。 方法 Task.WhenAny 會在集合中的任何方法完成執行時完成,如下列程式代碼範例所示:

await Task.WhenAny<bool>
(
  image.RotateTo (360, 4000),
  image.ScaleTo (2, 2000)
);
await image.ScaleTo (1, 2000);

在此範例中 Task.WhenAny ,方法呼叫包含兩個工作。 第一個工作會輪替影像超過 4 秒 (4000 毫秒),而第二個工作會將影像調整為 2 秒 (2000 毫秒)。 當第二個工作完成時 Task.WhenAny ,方法呼叫就會完成。 不過,即使 RotateTo 方法仍在執行中,第二 ScaleTo 個方法還是可以開始。

方法 Task.WhenAll 會在其集合中的所有方法都完成時完成,如下列程式代碼範例所示:

// 10 minute animation
uint duration = 10 * 60 * 1000;

await Task.WhenAll (
  image.RotateTo (307 * 360, duration),
  image.RotateXTo (251 * 360, duration),
  image.RotateYTo (199 * 360, duration)
);

在此範例中 Task.WhenAll ,方法呼叫包含三個工作,每個工作都會執行超過 10 分鐘。 每個Task旋轉的旋轉數不同 360 度 – 307 輪替、251 RotateXTo次旋轉RotateTo,以及 199 次旋轉RotateYTo。 這些值是質數,因此可確保輪替不會同步處理,因此不會產生重複的模式。

下列螢幕快照顯示每個平臺上的多個輪替:

復合動畫

取消動畫

應用程式可以使用對 CancelAnimations 擴充方法的呼叫來取消一或多個動畫,如下列程式代碼範例所示:

image.CancelAnimations();

這會立即取消目前在 實例上 Image 執行的所有動畫。

摘要

本文示範如何使用 ViewExtensions 類別建立和取消動畫。 這個類別提供擴充方法,可用來建構旋轉、縮放、轉譯和淡出 VisualElement 實例的簡單動畫。