Vlastní animace
Třída .NET Multi-Platform App UI (.NET MAUI) Animation je stavební blok všech animací .NET MAUI s metodami rozšíření ve ViewExtensions třídě, které vytvářejí jeden nebo více Animation objektů.
Při vytváření objektu Animation , včetně počátečních a koncových hodnot animované vlastnosti, a zpětného volání, které změní hodnotu vlastnosti, musí být zadáno několik parametrů. Objekt Animation může také udržovat kolekci podřízených animací, které lze spustit a synchronizovat. Další informace najdete v tématu Podřízené animace.
Spuštění animace vytvořené pomocí Animation třídy, která může nebo nemusí obsahovat podřízené animace, je dosaženo voláním Commit metody. Tato metoda určuje dobu trvání animace a mimo jiné zpětné volání, které řídí, zda se má animace opakovat.
Poznámka:
Třída Animation má IsEnabled vlastnost, kterou lze prozkoumat a určit, zda byly animace zakázány operačním systémem, například při aktivaci režimu úspory energie.
Animace v Androidu respektují nastavení systémové animace:
- Pokud jsou animace systému zakázané (funkcemi přístupnosti nebo vývojářskými funkcemi), nové animace se okamžitě přesunou do stavu dokončení.
- Pokud je režim úspory energie zařízení aktivován, zatímco animace probíhají, animace okamžitě přeskočí do stavu dokončení.
- Pokud je doba trvání animace zařízení nastavená na nulu (zakázáno), zatímco animace probíhají a verze rozhraní API je 33 nebo vyšší, animace okamžitě přeskočí do stavu dokončení.
Vytvoření animace
Při vytváření objektu Animation se obvykle vyžaduje minimálně tři parametry, jak je znázorněno v následujícím příkladu kódu:
var animation = new Animation(v => image.Scale = v, 1, 2);
V tomto příkladu Scale je animace vlastnosti Image instance definována z hodnoty 1 na hodnotu 2. Animované hodnoty se předají zpětnému volání určenému jako první argument, kde se používá ke změně hodnoty Scale vlastnosti.
Animace se spustí voláním Commit metody:
animation.Commit(this, "SimpleAnimation", 16, 2000, Easing.Linear, (v, c) => image.Scale = 1, () => true);
Poznámka:
Metoda Commit nevrací Task
objekt. Místo toho se oznámení poskytují prostřednictvím metod zpětného volání.
V metodě jsou zadány Commit následující argumenty:
- První argument (
owner
) identifikuje vlastníka animace. Může se jednat o vizuální prvek, na kterém se animace použije, nebo jiný vizuální prvek, například stránku. - Druhý argument (
name
) identifikuje animaci s názvem. Jméno se zkombinuje s vlastníkem a jedinečně identifikuje animaci. Tuto jedinečnou identifikaci pak můžete použít k určení, jestli je animace spuštěná (AnimationIsRunning) nebo jestli ji chcete zrušit (AbortAnimation). - Třetí argument (
rate
) označuje počet milisekund mezi každým voláním metody zpětného volání definovanou v konstruktoru Animation . - Čtvrtý argument (
length
) označuje dobu trvání animace v milisekundách. - Pátý argument (Easing) definuje funkci pro usnadnění, která se má použít v animaci. Případně lze funkci easing zadat jako argument konstruktoru Animation . Další informace o usnadnění funkcí najdete v tématu Easing Functions.
- Šestý argument (
finished
) je zpětné volání, které se spustí po dokončení animace. Tento zpětný volání přebírá dva argumenty, přičemž první argument označuje konečnou hodnotu a druhý argument jebool
nastavený natrue
hodnotu, pokud byla animace zrušena. Alternativněfinished
lze zpětné volání zadat jako argument konstruktoru Animation . Pokud jsou však při jedné animacifinished
zadány zpětná volání v Animation konstruktoru i Commit metodě, spustí se pouze zpětné volání zadané v Commit metodě. - Sedmý argument (
repeat
) je zpětné volání, které umožňuje opakování animace. Volá se na konci animace a návrattrue
označuje, že by se animace měla opakovat.
V předchozím příkladu je celkovým efektem vytvoření animace, která pomocí funkce usnadnění zvýší Scale vlastnost Image instance z 1 na 2 sekundy (2000 milisekund Linear ). Pokaždé, když se animace dokončí, Scale její vlastnost se obnoví na hodnotu 1 a animace se opakuje.
Poznámka:
Souběžné animace, které běží nezávisle na sobě, lze vytvořit vytvořením objektu Animation pro každou animaci a následným voláním Commit metody pro každou animaci.
Podřízené animace
Třída Animation také podporuje podřízené animace, což jsou Animation objekty, ke kterým se ostatní Animation objekty přidají jako podřízené objekty. To umožňuje spustit a synchronizovat řadu animací. Následující příklad kódu ukazuje vytváření a spouštění podřízených animací:
var parentAnimation = new Animation();
var scaleUpAnimation = new Animation(v => image.Scale = v, 1, 2, Easing.SpringIn);
var rotateAnimation = new Animation(v => image.Rotation = v, 0, 360);
var scaleDownAnimation = new Animation(v => image.Scale = v, 2, 1, Easing.SpringOut);
parentAnimation.Add(0, 0.5, scaleUpAnimation);
parentAnimation.Add(0, 1, rotateAnimation);
parentAnimation.Add(0.5, 1, scaleDownAnimation);
parentAnimation.Commit(this, "ChildAnimations", 16, 4000, null, (v, c) => SetIsEnabledButtonState(true, false));
Příklad kódu lze také napsat výstižněji:
new Animation
{
{ 0, 0.5, new Animation (v => image.Scale = v, 1, 2) },
{ 0, 1, new Animation (v => image.Rotation = v, 0, 360) },
{ 0.5, 1, new Animation (v => image.Scale = v, 2, 1) }
}.Commit (this, "ChildAnimations", 16, 4000, null, (v, c) => SetIsEnabledButtonState (true, false));
V obou příkladech se vytvoří nadřazený Animation objekt, do kterého se pak přidají další Animation objekty. První dva argumenty Add metody určují, kdy začít a dokončit podřízenou animaci. Hodnoty argumentů musí být v rozmezí od 0 do 1 a představují relativní období v rámci nadřazené animace, kterou bude zadaná podřízená animace aktivní. Proto v tomto příkladu scaleUpAnimation
bude aktivní pro první polovinu animace, scaleDownAnimation
bude aktivní pro druhou polovinu animace a rotateAnimation
bude aktivní po celou dobu trvání.
Celkový efekt tohoto příkladu spočívá v tom, že animace probíhá po dobu 4 sekund (4000 milisekund). Animuje scaleUpAnimation
Scale vlastnost od 1 do 2, více než 2 sekundy. Potom scaleDownAnimation
animuje Scale vlastnost od 2 do 1, více než 2 sekundy. I když se vyskytují obě animace škálování, rotateAnimation
animuje Rotation vlastnost od 0 do 360, více než 4 sekundy. Obě animace škálování také používají funkce pro usnadnění. SpringIn Funkce easing způsobí Image počáteční zmenšení instance před zvětšením a SpringOut easing funkce způsobíImage, že se zmenší, než je její skutečná velikost na konci celé animace.
Mezi objektem Animation , který používá podřízené animace, existuje několik rozdílů a mezi objektem, který:
- Při použití podřízených animací
finished
zpětné volání u podřízené animace označuje, kdy se podřízená položka dokončila, afinished
zpětné volání předané Commit metodě označuje, kdy byla dokončena celá animace. - Pokud použijete podřízené animace, vrácení
true
z zpětnéhorepeat
volání metody Commit nezpůsobí opakování animace, ale animace se bude dál spouštět bez nových hodnot. - Pokud do Commit metody zahrnete funkci pro usnadnění a funkce pro usnadnění vrátí hodnotu větší než 1, animace se ukončí. Pokud easing funkce vrátí hodnotu menší než 0, hodnota se uchytne na 0. Chcete-li použít funkci easing, která vrací hodnotu menší než 0 nebo větší než 1, musí být určena v jedné z podřízených animací, nikoli v Commit metodě.
Třída Animation také obsahuje WithConcurrent metody, které lze použít k přidání podřízených animací do nadřazeného Animation objektu. Jejich begin
hodnoty a finish
argumenty ale nejsou omezeny na 0 až 1, ale pouze tato část podřízené animace, která odpovídá rozsahu 0 až 1, bude aktivní. Pokud například WithConcurrent volání metody definuje podřízenou animaci, která cílí na Scale vlastnost od 1 do 6, ale s begin
hodnotami finish
-2 a 3, begin
hodnota -2 odpovídá Scale hodnotě 1 a finish
hodnota 3 odpovídá Scale hodnotě 6. Vzhledem k tomu, že hodnoty mimo rozsah 0 a 1 nehrají žádnou roli v animaci, Scale vlastnost bude animované pouze od 3 do 6.
Zrušení animace
Aplikace může vlastní animaci zrušit voláním AbortAnimation metody rozšíření:
this.AbortAnimation ("SimpleAnimation");
Vzhledem k tomu, že animace jsou jedinečně identifikovány kombinací vlastníka animace a názvu animace, musí být zadán vlastník a jméno zadané při spuštění animace, aby se zrušila. Proto tento příklad okamžitě zruší animaci, SimpleAnimation
která je vlastněná stránkou.
Vytvoření vlastní animace
Zde uvedené příklady zatím ukázaly animace, které lze stejně dosáhnout metodami ve ViewExtensions třídě. Výhodou Animation třídy však je, že má přístup k metodě zpětného volání, která se spustí při změně animované hodnoty. To umožňuje zpětnému volání implementovat jakoukoli požadovanou animaci. Například následující příklad kódu animuje BackgroundColor vlastnost stránky nastavením na Color hodnoty vytvořené Color.FromHsla
metodou, přičemž hodnoty odstínu v rozsahu od 0 do 1:
new Animation (callback: v => BackgroundColor = Color.FromHsla (v, 1, 0.5),
start: 0,
end: 1).Commit (this, "Animation", 16, 4000, Easing.Linear, (v, c) => BackgroundColor = Colors.Black);
Výsledná animace poskytuje vzhled posouvání pozadí stránky pomocí barev duhy.
Vytvoření vlastní metody rozšíření animace
Rozšiřující metody ve ViewExtensions třídě animují vlastnost z její aktuální hodnoty na zadanou hodnotu. Díky tomu je obtížné vytvořit například animační metodu ColorTo
, která se dá použít k animaci barvy z jedné hodnoty do druhé. Důvodem je to, že různé ovládací prvky mají různé vlastnosti typu Color. VisualElement I když třída definuje BackgroundColor vlastnost, není to vždy požadovaná Color
vlastnost k animaci.
Řešením tohoto problému je, ColorTo
že metoda cílí na konkrétní Color
vlastnost. Místo toho je možné ji zapsat metodou zpětného volání, která předá interpolovanou Color hodnotu zpět volajícímu. Kromě toho bude metoda trvat počáteční a koncové Color argumenty.
Tuto ColorTo
metodu lze implementovat jako rozšiřující metodu, která metodu Animate AnimationExtensions ve třídě používá k poskytování jeho funkcí. Důvodem je to, že metodu Animate lze použít k cílení vlastností, které nejsou typu double
, jak je znázorněno v následujícím příkladu kódu:
public static class ViewExtensions
{
public static Task<bool> ColorTo(this VisualElement self, Color fromColor, Color toColor, Action<Color> callback, uint length = 250, Easing easing = null)
{
Func<double, Color> transform = (t) =>
Color.FromRgba(fromColor.Red + t * (toColor.Red - fromColor.Red),
fromColor.Green + t * (toColor.Green - fromColor.Green),
fromColor.Blue + t * (toColor.Blue - fromColor.Blue),
fromColor.Alpha + t * (toColor.Alpha - fromColor.Alpha));
return ColorAnimation(self, "ColorTo", transform, callback, length, easing);
}
public static void CancelAnimation(this VisualElement self)
{
self.AbortAnimation("ColorTo");
}
static Task<bool> ColorAnimation(VisualElement element, string name, Func<double, Color> transform, Action<Color> callback, uint length, Easing easing)
{
easing = easing ?? Easing.Linear;
var taskCompletionSource = new TaskCompletionSource<bool>();
element.Animate<Color>(name, transform, callback, 16, length, easing, (v, c) => taskCompletionSource.SetResult(c));
return taskCompletionSource.Task;
}
}
Metoda Animate vyžaduje transform
argument, což je metoda zpětného volání. Vstup do tohoto zpětného volání je vždy v rozsahu double
od 0 do 1. V tomto příkladu ColorTo
tedy metoda definuje vlastní transformaci Func
, která přijímá double
hodnotu od 0 do 1 a která vrátí Color hodnotu odpovídající této hodnotě. Hodnota Color je vypočítána interpolací Red
, Green
, Blue
a Alpha
hodnotami dvou zadaných Color argumentů. Hodnota Color se pak předá metodě zpětného volání, která se má použít na vlastnost. Tento přístup umožňuje ColorTo
metodě animovat jakoukoli zadanou Color vlastnost:
await Task.WhenAll(
label.ColorTo(Colors.Red, Colors.Blue, c => label.TextColor = c, 5000),
label.ColorTo(Colors.Blue, Colors.Red, c => label.BackgroundColor = c, 5000));
await this.ColorTo(Color.FromRgb(0, 0, 0), Color.FromRgb(255, 255, 255), c => BackgroundColor = c, 5000);
await boxView.ColorTo(Colors.Blue, Colors.Red, c => boxView.Color = c, 4000);
V tomto příkladu ColorTo
kódu metoda animuje TextColor
a BackgroundColor vlastnosti Label, BackgroundColor vlastnost stránky a Color
vlastnost .BoxView