Maui: [Spéc] Transitions

Créé le 18 mai 2020  ·  7Commentaires  ·  Source: dotnet/maui

Transitions

Maui dispose déjà d'une API d'animations complète permettant de créer un contenu live et fluide sur une page. Cependant, que se passe-t-il lors de la navigation entre les pages ?.

Cette spécification définit une API de transitions Maui. Nous avons deux types de transitions bien différenciées :

  • Transitions traditionnelles : Traditionnellement, les transitions entre les différentes pages impliquaient des transitions d'entrée et de sortie qui animaient des hiérarchies de vues entières indépendantes les unes des autres.
  • Transitions d'éléments partagés : plusieurs fois, il existe des éléments communs aux deux activités et la possibilité de faire la transition de ces éléments partagés séparément met l'accent sur la continuité entre les transitions et brise les limites des activités lorsque l'utilisateur navigue dans l'application.

shared_transitions

API

Transitions traditionnelles

Pour les transitions traditionnelles, nous avons besoin d'une nouvelle énumération avec les transitions supportées :

public enum NavigationTransitionType
{
    None,
    Fade,
    Flip,
    Scale,
    SlideFromLeft,
    SlideFromRight,
    SlideFromTop,
    SlideFromBottom,
    Turnstile
}

Et, incluez de nouvelles propriétés dans la page pour autoriser les transitions de page à l'aide de NavigationPage et Shell :

  • TransitionType : L'effet de transition utilisé.
  • TransitionDuration : La durée de transition en millisecondes.
public static readonly BindableProperty TransitionTypeProperty =
     BindableProperty.Create(nameof(TransitionType), typeof(NavigationTransitionType),   typeof(NavigationPage), PageTransitionType.None,
     BindingMode.TwoWay, null);

public NavigationTransitionType TransitionType
{
    get { return (NavigationTransitionType)GetValue(TransitionTypeProperty); }
    set { SetValue(TransitionTypeProperty, value); }
}

public static readonly BindableProperty TransitionDurationProperty =
     BindableProperty.Create(nameof(TransitionDuration), typeof(double), typeof(NavigationPage), 500d,
     BindingMode.TwoWay, null);

public double TransitionDuration
{
    get { return (double)GetValue(TransitionDurationProperty); }
    set { SetValue(TransitionDurationProperty, value); }
}

Transitions d'éléments partagés

D'un autre côté, nous avons besoin d'un moyen pour permettre les transitions d'éléments partagés. La clé est un moyen de _"lier"_ le même élément disponible dans deux pages différentes.

Nous aurons la propriété TransitionTag attachée aux éléments pris en charge hérités de View :

public static readonly BindableProperty TransitionTagProperty =    
     BindableProperty.CreateAttached("TransitionTag", typeof(int), typeof(Transition), 0,
propertyChanged: OnPropertyChanged);

L'utilisation serait :

<Image Source="xamarin.jpg" TransitionTag="logo" WidthRequest="100" />

Marquez le contrôle à faire la transition dans la page source.

<Image Source="xamarin.jpg" TransitionTag="logo" WidthRequest="300" />

Et balisez le contrôle à transitionner dans la page de destination.

Scénarios

Voyons quelques exemples.

Exemple XAML

Un exemple utilisant des transitions entre les pages :

<ContentPage
     TransitionType=“SlideFromBottom”
     TransitionDuration="750" />

Un exemple utilisant des éléments de transition partagés :

Page 1:

<Image  
     Source="xamagon_preview.png"
     TransitionTag="xamagon"/>

Page 2:

<Image  
     Source="xamagon.png"
     TransitionTag="xamagon"/>

Remarques

  • Les TransitionTag dans les pages source et destination doivent correspondre pour afficher la transition.
  • Vous pouvez animer plusieurs vues à la fois, mais chaque TransitionTag d'une page doit être unique.

Difficulté : Moyenne

animation 🎬 enhancement proposal-open

Commentaire le plus utile

Concernant les transitions partagées, veuillez noter que si vous souhaitez effectuer une transition à partir d'une liste d'éléments (par exemple une vue Collection) la propriété "TransitionTag" pourrait ne pas être suffisante pour identifier la vue que vous souhaitez animer.

Imaginez un DataTemplate avec une liste d'éléments contenant une image et un texte, chaque image est différente mais le TransitionTag est toujours le même (par exemple : "ImageToTransition").

Lorsque vous appuyez sur un élément, le moteur de rendu de navigation doit savoir exactement quel élément doit être traduit, et si vous avez une seule balise pour toutes vos images dans CollectionView, cela peut poser problème.

Dans mon plugin, j'ai résolu en utilisant une propriété TransitionGroup que j'utilise pour identifier l'élément à traduire.

J'aimerais contribuer à cette fonctionnalité mais mon code pour Android n'est pas assez stable (il y a des problèmes avec ChildFragments lors de l'utilisation de TabbedPages/MasterPage, mais en shell je pense que c'est bien), aussi dans iOS je poursuis quelques hacks pour faire de bonnes transitions .

J'ai retravaillé beaucoup de code de la première version et maintenant ça a l'air mieux mais je ne pense pas que ce soit assez bon pour aller dans le noyau, mais je suis prêt à aider et à contribuer si nécessaire
https://github.com/GiampaoloGabba/Xamarin.Plugin.SharedTransitions

Tous les 7 commentaires

Suggestion

Peut-être une propriété qui reçoit une animation au lieu d'un enum ?
Pour pouvoir étendre et recevoir des animations personnalisées qui doivent implémenter une interface ITransitionAnimation .
Et quelques animations prédéfinies à utiliser comme NamedSize sur les polices

Exemple:

<ContentPage
     Transition=“{local:MyCustomTransition}"
     TransitionDuration="750" />

Ou des "Transitions nommées" prédéfinies

<ContentPage
     Transition=“Fade"
     TransitionDuration="750" />

Concernant les transitions partagées, veuillez noter que si vous souhaitez effectuer une transition à partir d'une liste d'éléments (par exemple une vue Collection) la propriété "TransitionTag" pourrait ne pas être suffisante pour identifier la vue que vous souhaitez animer.

Imaginez un DataTemplate avec une liste d'éléments contenant une image et un texte, chaque image est différente mais le TransitionTag est toujours le même (par exemple : "ImageToTransition").

Lorsque vous appuyez sur un élément, le moteur de rendu de navigation doit savoir exactement quel élément doit être traduit, et si vous avez une seule balise pour toutes vos images dans CollectionView, cela peut poser problème.

Dans mon plugin, j'ai résolu en utilisant une propriété TransitionGroup que j'utilise pour identifier l'élément à traduire.

J'aimerais contribuer à cette fonctionnalité mais mon code pour Android n'est pas assez stable (il y a des problèmes avec ChildFragments lors de l'utilisation de TabbedPages/MasterPage, mais en shell je pense que c'est bien), aussi dans iOS je poursuis quelques hacks pour faire de bonnes transitions .

J'ai retravaillé beaucoup de code de la première version et maintenant ça a l'air mieux mais je ne pense pas que ce soit assez bon pour aller dans le noyau, mais je suis prêt à aider et à contribuer si nécessaire
https://github.com/GiampaoloGabba/Xamarin.Plugin.SharedTransitions

Btw beaucoup de mon code pourrait être grandement simplifié si certaines propriétés peuvent être intégrées dans le noyau principal

@felipebaltazar Cela pourrait être quelque chose de similaire à la proposition de créer des transitions personnalisées dans TabView https://github.com/xamarin/Xamarin.Forms/issues/10773 Je ferai quelques tests et après cela, nous examinerons la spécification.

@GiampaoloGabba Ce sera certainement formidable d'avoir vos commentaires sur cette API. Si vous souhaitez contribuer, comme dans Xamarin.Forms, nous accepterons les PR et je serai ravi de vous aider. Concernant le paramètre que vous indiquez pour les collections, je l'ai revu et vous avez raison. Mnn, nous pouvons ajouter une propriété supplémentaire pour couvrir ces cas ( TransitionGroup ), ou peut-être en interne si le parent de l'élément est une collection, créer le groupe automatiquement.

ou peut-être en interne si le parent de l'élément est une collection, créez le groupe automatiquement.

J'ai essayé cette approche mais c'était un peu difficile. Par exemple, dans une vue de collection, nous pouvons démarrer une navigation basée sur le changement SelectedItem.
Il était beaucoup plus facile de "gifler" une propriété pour la regrouper, puis de laisser l'utilisateur décider quand et comment l'utiliser :)

Au fait, je prévois d'écrire ici un petit document couvrant l'architecture de base que j'ai utilisée pour développer cela (comment suivre les transitions et comment y arriver dans iOS, car il n'y a pas de support natif pour cela et j'ai dû tout développer à la main , alors que c'est beaucoup plus facile dans Android, si vous excluez les fragments enfants générés par tappedpage et MasterDetail)

Juste au cas où il y aurait peut-être de bonnes idées à porter ici et à exclure les mauvaises, ce qui, j'en suis sûr, sera beaucoup :)

Ça sonne bien @GiampaoloGabba , merci !

@felipebaltazar Cela pourrait être quelque chose de similaire à la proposition de créer des transitions personnalisées dans TabView xamarin/Xamarin.Forms#10773 Je ferai quelques tests et après cela, nous examinerons le Spec.

Ça a l'air bien!!!!
J'ai fait quelques animations sur le dépôt Xamarin.Forms.Skeleton , peut-être que ça peut aider pour de nouvelles idées... Je ne sais pas...

https://github.com/HorusSoftwareUY/Xamarin.Forms.Skeleton

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

mhrastegary77 picture mhrastegary77  ·  3Commentaires

probonopd picture probonopd  ·  50Commentaires

sim756 picture sim756  ·  16Commentaires

PureWeen picture PureWeen  ·  21Commentaires

Amine-Smahi picture Amine-Smahi  ·  3Commentaires