中的簡單動畫 Xamarin.Forms
ViewExtensions 類別提供可用來建構簡單動畫的擴充方法。 本文示範如何使用 ViewExtensions 類別建立和取消動畫。
類別 ViewExtensions
提供下列擴充方法,可用來建立簡單的動畫:
CancelAnimations
取消任何動畫。FadeTo
以Opacity
動畫顯示 的VisualElement
屬性。RelScaleTo
會將動畫累加增加或減少套用至Scale
的VisualElement
屬性。RotateTo
以Rotation
動畫顯示 的VisualElement
屬性。RelRotateTo
會將動畫累加增加或減少套用至Rotation
的VisualElement
屬性。RotateXTo
以RotationX
動畫顯示 的VisualElement
屬性。RotateYTo
以RotationY
動畫顯示 的VisualElement
屬性。ScaleTo
以Scale
動畫顯示 的VisualElement
屬性。ScaleXTo
以ScaleX
動畫顯示 的VisualElement
屬性。ScaleYTo
以ScaleY
動畫顯示 的VisualElement
屬性。TranslateTo
以動畫顯示 的TranslationX
VisualElement
和TranslationY
屬性。
根據預設,每個動畫將需要 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,這樣會防止其他旋轉。
下列螢幕快照顯示每個平臺上的輪替進行中:
相對旋轉
下列程式代碼範例示範如何使用 RelRotateTo
方法來累加增加或減少 Rotation
的 Image
屬性:
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)。 這會影響將影像大小擴充為其大小兩倍的效果。
下列螢幕快照顯示每個平臺上的調整進行中:
相對調整
下列程式代碼範例示範如何使用 RelScaleTo
方法來建立 Scale
屬性的 Image
動畫效果:
await image.RelScaleTo (2, 2000);
此程式代碼會將實例的大小相應增加至 2 秒 (2000 毫秒) 的兩倍,以產生動畫 Image
效果。 方法 RelScaleTo
會取得動畫開頭的目前 Scale
屬性值,然後從該值調整為值加上第一個自變數 (2)。 這可確保每個動畫一律會從起始位置調整為 2。
使用錨點調整和旋轉
AnchorX
和 AnchorY
屬性會設定 和 Scale
屬性的Rotation
縮放或旋轉中心。 因此,其值也會影響 RotateTo
和 ScaleTo
方法。
Image
假設已放置在版面配置中央的 ,下列程式代碼範例會藉由設定其 AnchorY
屬性,示範在版面配置中央旋轉影像:
double radius = Math.Min(absoluteLayout.Width, absoluteLayout.Height) / 2;
image.AnchorY = radius / image.Height;
await image.RotateTo(360, 2000);
若要繞 Image
版面配置中心旋轉實例,和 AnchorX
AnchorY
屬性必須設定為相對於 寬度和高度 Image
的值。 在此範例中,會將的中心 Image
定義為配置的中心,因此預設值 AnchorX
0.5 不需要變更。 不過,屬性 AnchorY
會重新定義為從 頂端 Image
到版面配置中心點的值。 這可確保 Image
在版面配置中心點周圍進行 360 度的完整旋轉,如下列螢幕快照所示:
翻譯
下列程式代碼範例示範如何使用 TranslateTo
方法來建立 TranslationX
和 TranslationY
屬性的 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
方法會在沒有運算符的情況下執行,並立即傳回 ,然後開始第一個await
ScaleTo
動畫。 第 await
一個 ScaleTo
方法呼叫上的運算符會延遲第二 ScaleTo
個方法呼叫,直到第一個 ScaleTo
方法呼叫完成為止。 此時動畫 RotateTo
已完成一半, Image
並將旋轉 180 度。 在最後 2 秒(2000 毫秒)期間,第二 ScaleTo
個動畫和 RotateTo
動畫都已完成。
同時執行多個異步方法
static
Task.WhenAny
和 Task.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
實例的簡單動畫。