Udostępnij za pośrednictwem


Animacja niestandardowa

Klasa .NET Multi-platform App UI (.NET MAUI) Animation jest blokiem konstrukcyjnym wszystkich animacji MAUI platformy .NET z metodami rozszerzenia w ViewExtensions klasie tworzącymi co najmniej jeden Animation obiekt.

Podczas tworzenia Animation obiektu należy określić szereg parametrów, w tym wartości początkowe i końcowe właściwości animowanej oraz wywołanie zwrotne, które zmienia wartość właściwości. Obiekt Animation może również obsługiwać kolekcję animacji podrzędnych, które można uruchamiać i synchronizować. Aby uzyskać więcej informacji, zobacz Animacje podrzędne.

Uruchomienie animacji utworzonej Animation za pomocą klasy , która może lub nie może zawierać animacji podrzędnych, jest osiągana przez wywołanie Commit metody . Ta metoda określa czas trwania animacji, a wśród innych elementów wywołanie zwrotne, które kontroluje, czy powtarzać animację.

Uwaga

Klasa Animation ma IsEnabled właściwość, którą można zbadać, aby określić, czy animacje zostały wyłączone przez system operacyjny, na przykład w przypadku aktywowania trybu oszczędzania energii.

W systemie Android animacje przestrzegają ustawień animacji systemu:

  • Jeśli animacje systemu są wyłączone (przez funkcje ułatwień dostępu lub funkcje dla deweloperów), nowe animacje będą natychmiast przechodzić do ich stanu zakończenia.
  • Jeśli tryb oszczędzania energii urządzenia jest aktywowany, gdy animacje są w toku, animacje natychmiast przeskoczą do stanu zakończenia.
  • Jeśli czasy trwania animacji urządzenia są ustawione na zero (wyłączone), podczas gdy animacje są w toku, a wersja interfejsu API wynosi 33 lub nowsza, animacje natychmiast przeskoczą do stanu zakończenia.

Tworzenie animacji

Podczas tworzenia Animation obiektu zwykle wymagane są co najmniej trzy parametry, jak pokazano w poniższym przykładzie kodu:

var animation = new Animation(v => image.Scale = v, 1, 2);

W tym przykładzie animacja Scale właściwości Image wystąpienia jest definiowana z wartości 1 do wartości 2. Animowana wartość jest przekazywana do wywołania zwrotnego określonego jako pierwszy argument, w którym jest używana do zmiany wartości Scale właściwości.

Animacja jest uruchamiana za pomocą wywołania Commit metody :

animation.Commit(this, "SimpleAnimation", 16, 2000, Easing.Linear, (v, c) => image.Scale = 1, () => true);

Uwaga

Metoda Commit nie zwraca Task obiektu. Zamiast tego powiadomienia są dostarczane za pomocą metod wywołania zwrotnego.

W metodzie Commit określono następujące argumenty:

  • Pierwszy argument (owner) identyfikuje właściciela animacji. Może to być element wizualizacji, na którym jest stosowana animacja, lub inny element wizualizacji, taki jak strona.
  • Drugi argument (name) identyfikuje animację o nazwie. Nazwa jest łączona z właścicielem w celu unikatowego zidentyfikowania animacji. Tej unikatowej identyfikacji można następnie użyć do określenia, czy animacja jest uruchomiona (AnimationIsRunning), czy też ją anulować (AbortAnimation).
  • Trzeci argument (rate) wskazuje liczbę milisekund między każdym wywołaniem metody wywołania zwrotnego zdefiniowanej w konstruktorze Animation .
  • Czwarty argument (length) wskazuje czas trwania animacji w milisekundach.
  • Piąty argument (Easing) definiuje funkcję złagodzenia, która ma być używana w animacji. Alternatywnie funkcję złagodzenia można określić jako argument konstruktora Animation . Aby uzyskać więcej informacji na temat funkcji ułatwiania, zobacz Funkcje easing.
  • Szósty argument (finished) to wywołanie zwrotne, które zostanie wykonane po zakończeniu animacji. To wywołanie zwrotne przyjmuje dwa argumenty, z pierwszym argumentem wskazującym wartość końcową, a drugi argument jest bool ustawiony na true wartość , jeśli animacja została anulowana. Alternatywnie finished wywołanie zwrotne można określić jako argument konstruktora Animation . Jednak w przypadku pojedynczej animacji, jeśli finished wywołania zwrotne są określone zarówno w konstruktorze Animation , jak i metodzie Commit , zostanie wykonane tylko wywołanie zwrotne określone w Commit metodzie.
  • Siódmy argument (repeat) to wywołanie zwrotne, które umożliwia powtórzenie animacji. Jest wywoływana na końcu animacji i zwracana true wskazuje, że animacja powinna być powtarzana.

W powyższym przykładzie ogólny efekt polega na utworzeniu animacji, która zwiększa Scale właściwość Image wystąpienia z zakresu od 1 do 2, ponad 2 sekund (2000 milisekund), używając Linear funkcji złagodzenia. Za każdym razem, gdy animacja zostanie ukończona, jej Scale właściwość zostanie zresetowana do wartości 1, a animacja będzie powtarzana.

Uwaga

Współbieżne animacje, które są uruchamiane niezależnie od siebie, można utworzyć przez utworzenie Animation obiektu dla każdej animacji, a następnie wywołanie Commit metody dla każdej animacji.

Animacje podrzędne

Klasa Animation obsługuje również animacje podrzędne, które są Animation obiektami, do których są dodawane inne Animation obiekty jako obiekty podrzędne. Dzięki temu można uruchamiać i synchronizować serię animacji. W poniższym przykładzie kodu pokazano tworzenie i uruchamianie animacji podrzędnych:

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));

Alternatywnie przykład kodu można napisać bardziej zwięzłie:

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));

W obu przykładach tworzony jest obiekt nadrzędny Animation , do którego są następnie dodawane dodatkowe Animation obiekty. Pierwsze dwa argumenty Add metody określają, kiedy rozpocząć i zakończyć animację podrzędną. Wartości argumentów muszą należeć do przedziału od 0 do 1 i reprezentować względny okres w animacji nadrzędnej, że określona animacja podrzędna będzie aktywna. W związku z tym w tym przykładzie scaleUpAnimation wartość będzie aktywna w pierwszej połowie animacji, scaleDownAnimation wartość będzie aktywna przez drugą połowę animacji i rotateAnimation będzie aktywna przez cały czas trwania.

Ogólny efekt tego przykładu polega na tym, że animacja występuje ponad 4 sekundy (4000 milisekund). Obiekt scaleUpAnimation animuje Scale właściwość z zakresu od 1 do 2, ponad 2 sekundy. Następnie scaleDownAnimation animuje Scale właściwość z 2 do 1, ponad 2 sekundy. Podczas gdy obie animacje skalowania występują, rotateAnimation właściwość animuje Rotation właściwość z zakresu od 0 do 360, ponad 4 sekundy. Obie animacje skalowania używają również funkcji złagodzenia. Funkcja SpringIn złagodzenia powoduje Image , że wystąpienie początkowo zmniejsza się przed uzyskaniem większego rozmiaru, a SpringOut funkcja złagodzenia powoduje Image , że wartość staje się mniejsza niż rzeczywisty rozmiar na końcu pełnej animacji.

Istnieje wiele różnic między obiektem Animation , który używa animacji podrzędnych, i taki, który nie:

  • W przypadku korzystania z animacji podrzędnych finished wywołanie zwrotne animacji podrzędnej wskazuje, kiedy element podrzędny został ukończony, a finished wywołanie zwrotne przekazane do Commit metody wskazuje, kiedy cała animacja została ukończona.
  • W przypadku korzystania z animacji podrzędnych powrót true z wywołania zwrotnego repeat metody Commit nie spowoduje powtórzenia animacji, ale animacja będzie nadal działać bez nowych wartości.
  • W przypadku włączenia funkcji złagodzenia w metodzie Commit , a funkcja easing zwraca wartość większą niż 1, animacja zostanie zakończona. Jeśli funkcja złagodzenia zwraca wartość mniejszą niż 0, wartość jest zaciśnięta do 0. Aby użyć funkcji złagodzenia, która zwraca wartość mniejszą niż 0 lub większą niż 1, musi być określona w jednej z animacji podrzędnych, a nie w metodzie Commit .

Klasa Animation zawiera WithConcurrent również metody, których można użyć do dodawania animacji podrzędnych do obiektu nadrzędnego Animation . Jednak ich begin wartości i finish argumentów nie są ograniczone do 0 do 1, ale tylko ta część animacji podrzędnej, która odpowiada zakresowi od 0 do 1, będzie aktywna. Jeśli na przykład WithConcurrent wywołanie metody definiuje animację podrzędną, która jest przeznaczona Scale dla właściwości z zakresu od 1 do 6, ale z wartościami begin i finish -2 i 3, begin wartość -2 odpowiada Scale wartości 1, a finish wartość 3 odpowiada Scale wartości 6. Ponieważ wartości spoza zakresu od 0 do 1 nie odgrywają żadnej części w animacji, Scale właściwość będzie animowana tylko z zakresu od 3 do 6.

Anulowanie animacji

Aplikacja może anulować animację niestandardową za pomocą wywołania AbortAnimation metody rozszerzenia:

this.AbortAnimation ("SimpleAnimation");

Ponieważ animacje są jednoznacznie identyfikowane przez kombinację właściciela animacji i nazwę animacji, właściciel i nazwa określona podczas uruchamiania animacji muszą zostać określone, aby ją anulować. W związku z tym ten przykład natychmiast anuluje animację o nazwie SimpleAnimation należącej do strony.

Tworzenie animacji niestandardowej

W przedstawionych tutaj przykładach pokazano do tej pory animacje, które można osiągnąć w równym stopniu przy użyciu metod w ViewExtensions klasie. Jednak zaletą Animation klasy jest to, że ma dostęp do metody wywołania zwrotnego, która jest wykonywana po zmianie animowanej wartości. Dzięki temu wywołanie zwrotne może zaimplementować dowolną żądaną animację. Na przykład poniższy przykład kodu animuje BackgroundColor właściwość strony, ustawiając ją na wartości utworzone przez Color.FromHsla metodę, z wartościami odcieni od 0 do Color 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);

Wynikowa animacja zapewnia wygląd tła strony przez kolory tęczy.

Tworzenie niestandardowej metody rozszerzenia animacji

Metody rozszerzeń w ViewExtensions klasie animują właściwość z bieżącej wartości na określoną wartość. Utrudnia to na przykład utworzenie metody animacji, ColorTo która może służyć do animowania koloru z jednej wartości na drugą. Dzieje się tak, ponieważ różne kontrolki mają różne właściwości typu Color. VisualElement Klasa definiuje BackgroundColor właściwość, ale nie zawsze jest to żądana Color właściwość do animowania.

Rozwiązaniem tego problemu jest brak ColorTo właściwości docelowej Color metody. Zamiast tego można go napisać za pomocą metody wywołania zwrotnego, która przekazuje wartość interpolowaną Color z powrotem do elementu wywołującego. Ponadto metoda będzie przyjmować argumenty początkowe i końcowe Color .

Metodę ColorTo można zaimplementować jako metodę rozszerzenia, która używa Animate metody w AnimationExtensions klasie w celu zapewnienia jej funkcjonalności. Jest to spowodowane tym, że Animate metoda może służyć do określania właściwości docelowych, które nie są typu double, jak pokazano w poniższym przykładzie kodu:

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 wymaga argumentu transform , który jest metodą wywołania zwrotnego. Dane wejściowe tego wywołania zwrotnego są zawsze double od 0 do 1. W związku z tym w tym przykładzie ColorTo metoda definiuje własną double transformacjęFunc, która akceptuje wartość z zakresu od 0 do 1 i zwraca wartość odpowiadającą Color tej wartości. Wartość Color jest obliczana przez interpolację Redwartości , , GreenBluei Alpha dwóch podanych Color argumentów. Następnie Color wartość jest przekazywana do metody wywołania zwrotnego, która ma zostać zastosowana do właściwości. Takie podejście umożliwia metodzie ColorTo animowanie dowolnej określonej Color właściwości:

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);

W tym przykładzie ColorTo kodu metoda animuje TextColor właściwości Labeli BackgroundColor obiektu , BackgroundColor właściwość strony i Color właściwość BoxView.