Maui already has a complete animations API allowing you to create a live and fluid content on a page. However, what happens when navigating between pages?.
This spec defines a Maui transitions API. We have two types of well-differentiated transitions:
For the traditional transitions, we need a new enumeration with the supported transitions:
public enum NavigationTransitionType
{
None,
Fade,
Flip,
Scale,
SlideFromLeft,
SlideFromRight,
SlideFromTop,
SlideFromBottom,
Turnstile
}
And, include new properties in the Page to allow page transitions using NavigationPage and Shell:
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); }
}
On the other hand, we need a way to allow the shared element transitions. The key is a way to _"link"_ the same item available in two different pages.
We will have the TransitionTag attached property to the supported elements inherited from View:
public static readonly BindableProperty TransitionTagProperty =
BindableProperty.CreateAttached("TransitionTag", typeof(int), typeof(Transition), 0,
propertyChanged: OnPropertyChanged);
The use would be:
<Image Source="xamarin.jpg" TransitionTag="logo" WidthRequest="100" />
Tag the control to transition in the source page.
<Image Source="xamarin.jpg" TransitionTag="logo" WidthRequest="300" />
And tag the control to transition in the destination page.
Let's see some examples.
A sample using transitions between pages:
<ContentPage
TransitionType=“SlideFromBottom”
TransitionDuration="750" />
A sample using shared transitions elements:
Page 1:
<Image
Source="xamagon_preview.png"
TransitionTag="xamagon"/>
Page 2:
<Image
Source="xamagon.png"
TransitionTag="xamagon"/>
TransitionTag
in source and destination page needs to match in order to display the transition.TransitionTag
in a page needs to be unique.Perhaps a property that receives an animation instead of an enum
?
To be able to extend and receive customized animations that need to implement some ITransitionAnimation
interface.
And some predefined animations to use like NamedSize
on fonts
Example:
<ContentPage
Transition=“{local:MyCustomTransition}"
TransitionDuration="750" />
Or predefined "Named Transitions"
<ContentPage
Transition=“Fade"
TransitionDuration="750" />
Regarding shared transitions, please note that if you want to make a transition from a list of items (for example a Collectionview) the "TransitionTag" property could not be enough to identify the view you want to animate.
Imagine a DataTemplate with a list of items containing an image and a text, every image is different but the TransitionTag is always the same (for example: "ImageToTransition").
When you tap an element, the Navigation Renderer need to know exaclty what element need to be translated, and if you have a single tag for all your images in the CollectionView this could be a problem.
In my plugin i resolved using a TransitionGroup property wich i use to identify the element to translate.
I would like to contribute to this feature but my code for Android is not stable enough (there are problems with ChildFragments when using TabbedPages/MasterPage, but in shell i think is fine), also in iOS i sue some hacks to make good transitions shape.
I reworked a lot of code from the first version and now looks better but i dont think is good enough to go in core, but i'm ready to help and contribute if needed
https://github.com/GiampaoloGabba/Xamarin.Plugin.SharedTransitions
Btw a lot of my code could be greatly simplified if some properties can be integrated in the main core
@felipebaltazar It could be something similar to the proposal to create custom transitions in TabView https://github.com/xamarin/Xamarin.Forms/issues/10773 I will do some tests and after that we will review the Spec.
@GiampaoloGabba It will definitely be great to have your feedback on this API. If you want to contribute, as in Xamarin.Forms we will accept PRs and I will be happy to help you. About the parameter that you indicate for collections, I have reviewed it and you are right. Mnn, we can add an extra property to cover these cases (TransitionGroup
), or perhaps internally if the parent of the element is a collection, create the group automatically.
or perhaps internally if the parent of the element is a collection, create the group automatically.
i tried this approach but it was a bit difficult. For example in a collectionview we can start a navigation based on the SelectedItem change.
It was much easier to "slap" a property for grouping and then let the user decide when and how to use it :)
Btw i'm planning to write here a small doc covering the basis architecture i used to develop this (how to track transitions and how to make it happen in iOS, because there is not native support to that and i had to develop everything by hand, while it is much easier in Android, if you exclude child fragments generated by tappedpage and MasterDetail)
Just in case there are maybe some good ideas to port here and exclude the bad ones, wich, i'm sure, will be a lot :)
Sounds good @GiampaoloGabba, thanks!
@felipebaltazar It could be something similar to the proposal to create custom transitions in TabView xamarin/Xamarin.Forms#10773 I will do some tests and after that we will review the Spec.
Sounds good!!!!
I've done some animations on Xamarin.Forms.Skeleton
repository, maybe it can help for new ideas... I don't know...
Most helpful comment
Regarding shared transitions, please note that if you want to make a transition from a list of items (for example a Collectionview) the "TransitionTag" property could not be enough to identify the view you want to animate.
Imagine a DataTemplate with a list of items containing an image and a text, every image is different but the TransitionTag is always the same (for example: "ImageToTransition").
When you tap an element, the Navigation Renderer need to know exaclty what element need to be translated, and if you have a single tag for all your images in the CollectionView this could be a problem.
In my plugin i resolved using a TransitionGroup property wich i use to identify the element to translate.
I would like to contribute to this feature but my code for Android is not stable enough (there are problems with ChildFragments when using TabbedPages/MasterPage, but in shell i think is fine), also in iOS i sue some hacks to make good transitions shape.
I reworked a lot of code from the first version and now looks better but i dont think is good enough to go in core, but i'm ready to help and contribute if needed
https://github.com/GiampaoloGabba/Xamarin.Plugin.SharedTransitions