-
Notifications
You must be signed in to change notification settings - Fork 493
Expand file tree
/
Copy pathExpanderAnimationBehavior.shared.cs
More file actions
94 lines (84 loc) · 3.68 KB
/
ExpanderAnimationBehavior.shared.cs
File metadata and controls
94 lines (84 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
using CommunityToolkit.Maui.Core;
using CommunityToolkit.Maui.Views;
namespace CommunityToolkit.Maui.Behaviors;
/// <summary>
/// A behavior that adds smooth expand and collapse animations to an <see cref="Views.Expander"/>.
/// </summary>
public partial class ExpanderAnimationBehavior : BaseBehavior<Views.Expander>, IExpansionController
{
/// <summary>
/// Gets or sets the easing function used when the expander collapses.
/// </summary>
[BindableProperty]
public partial Easing CollapsingEasing { get; set; } = ExpanderAnimationBehaviorDefaults.CollapsingEasing;
/// <summary>
/// Gets or sets the duration, in milliseconds, of the collapse animation.
/// </summary>
[BindableProperty]
public partial uint CollapsingLength { get; set; } = ExpanderAnimationBehaviorDefaults.CollapsingLength;
/// <summary>
/// Gets or sets the easing function used when the expander expands.
/// </summary>
[BindableProperty]
public partial Easing ExpandingEasing { get; set; } = ExpanderAnimationBehaviorDefaults.ExpandingEasing;
/// <summary>
/// Gets or sets the duration, in milliseconds, of the expansion animation.
/// </summary>
[BindableProperty]
public partial uint ExpandingLength { get; set; } = ExpanderAnimationBehaviorDefaults.ExpandingLength;
IExpansionController previousController = InstantExpansionController.Instance;
/// <summary>
/// Attaches the behavior to the specified expander and assigns it as the controller responsible for handling expansion animations.
/// </summary>
/// <param name="bindable">The Expander control to which the behavior is being attached to.</param>
protected override void OnAttachedTo(Views.Expander bindable)
{
base.OnAttachedTo(bindable);
previousController = bindable.ExpansionController ?? InstantExpansionController.Instance;
bindable.ExpansionController = this;
}
/// <summary>
/// Detaches the behavior from the specified Expander control and restores its previous expansion controller.
/// </summary>
/// <param name="bindable">The Expander control from which the behavior is being detached.</param>
protected override void OnDetachingFrom(Views.Expander bindable)
{
base.OnDetachingFrom(bindable);
if (bindable.ExpansionController == this)
{
bindable.ExpansionController = previousController;
}
}
/// <summary>
/// Performs the animation that runs when the expander transitions from a collapsed to an expanded state.
/// </summary>
/// <param name="expander">The Expander control that is expanding.</param>
public async Task OnExpandingAsync(Views.Expander expander)
{
if (expander.ContentHost is ContentView host && expander.Content is View view)
{
var tcs = new TaskCompletionSource();
var size = view.Measure(host.Width, double.PositiveInfinity);
var animation = new Animation(v => host.HeightRequest = v, 0, size.Height);
animation.Commit(expander, "ExpanderAnimation", 16, ExpandingLength, ExpandingEasing,
(v, c) => { tcs.TrySetResult(); host.HeightRequest = -1; });
await tcs.Task;
}
}
/// <summary>
/// Performs the animation that runs when the expander transitions from an expanded to a collapsed state.
/// </summary>
/// <param name="expander">The Expander control that is collapsing.</param>
public async Task OnCollapsingAsync(Views.Expander expander)
{
if (expander.ContentHost is ContentView host && expander.Content is View view)
{
var tcs = new TaskCompletionSource();
var size = view.Measure(host.Width, double.PositiveInfinity);
var animation = new Animation(v => host.HeightRequest = v, size.Height, 0);
animation.Commit(expander, "ExpanderAnimation", 16, CollapsingLength, CollapsingEasing,
(v, c) => { tcs.TrySetResult(); host.HeightRequest = 0; });
await tcs.Task;
}
}
}