Expander animation #1628
Replies: 6 comments 9 replies
-
Can you give a bit more information on what you are looking for here please. |
Beta Was this translation helpful? Give feedback.
-
Sure, I have just updated my question with more specific information. |
Beta Was this translation helpful? Give feedback.
-
@BeepBeepBopBop would you be able to supply a referenced video (e.g. YouTube or animated gif), so we can visualize what you're after? |
Beta Was this translation helpful? Give feedback.
-
You can implement this by hooking up animations to property change events on Expander.IsExpanded. In the following example:
When Expanded.IsExpanded=true
When Expanded.IsExpanded=false I do the converse. <!-- ExpandPage.xaml -->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="Maui.StackOverflow.ExpanderPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
x:Name="thisPage"
Title="ExpanderPage">
<VerticalStackLayout Padding="20,20,20,20" Spacing="20">
<toolkit:Expander x:Name="expander">
<toolkit:Expander.Header>
<Grid ColumnDefinitions="*,Auto">
<Label Text="What is C# used for?" />
<Label x:Name="caret" Grid.Column="1" Text="^" />
</Grid>
</toolkit:Expander.Header>
<ScrollView x:Name="contentOuter">
<VerticalStackLayout x:Name="contentInner" Padding="0,20,0,20" Spacing="20">
<Label Text="Some of the most important C# uses that enterprises benefit from include web app development, game development, workflow applications, and Windows services." />
<Label Text="TestGorilla" />
<Label Text="What is C# used for and which companies used it? - TestGorilla" />
</VerticalStackLayout>
</ScrollView>
</toolkit:Expander>
<Label Text="Is C# easier than C++?" />
<Label Text="Is it worth learning C# in 2024?" />
<Label Text="Is C# difficult to learn?" />
<Label Text="Is C# hard after Python?" />
</VerticalStackLayout>
</ContentPage> // ExpandPage.xaml.cs
using CommunityToolkit.Maui.Views;
namespace Maui.StackOverflow;
public partial class ExpanderPage : ContentPage
{
public ExpanderPage()
{
InitializeComponent();
expander.PropertyChanged += (s, e) =>
{
switch (e.PropertyName)
{
case nameof(Expander.IsExpanded):
if (expander.IsExpanded)
{
caret.RotateTo(180);
var animation = new Animation(v => contentOuter.HeightRequest = v, 0, contentInner.Height);
animation.Commit(this, "ExpandContent");
}
else
{
caret.RotateTo(0);
var animation = new Animation(v => contentOuter.HeightRequest = v, contentInner.Height, 0);
animation.Commit(this, "CollapseContent");
}
break;
}
};
}
} |
Beta Was this translation helpful? Give feedback.
-
@IeuanWalker I've updated the example to support dynamic content height |
Beta Was this translation helpful? Give feedback.
-
I decided to have another go at this. This implementation is a straight .NET MAUI implementation: <!-- XAML snippet -->
<VerticalStackLayout WidthRequest="400">
<Grid>
<Grid ColumnDefinitions="Auto,*">
<Path
x:Name="expanderChevron"
Aspect="Uniform"
Data="M0 0 16 16 0 0 8 11.207l-4-4V5.793l4 4 4-4v1.414 L8 11.207"
Fill="{AppThemeBinding Light=Black, Dark=White}"
HeightRequest="32"
WidthRequest="32" />
<Grid Grid.Column="1" Padding="4,0,4,0">
<Label Text="Title" VerticalOptions="Center" />
</Grid>
</Grid>
<Button Clicked="OnExpand" Opacity="0" />
</Grid>
<Grid Padding="4,0,4,0">
<VerticalStackLayout x:Name="outerContent" HeightRequest="1">
<Grid x:Name="innerContent" Padding="0,4,0,4">
<Label Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." />
</Grid>
</VerticalStackLayout>
</Grid>
</VerticalStackLayout> And the corresponding code behind: // Code behind
public uint AnimDuration { get; set; } = 100;
bool isExpanded = false;
public bool IsExpanded
{
get => isExpanded;
set
{
if (isExpanded == value) return;
this.Dispatcher.Dispatch(async () =>
{
var animation = new ContentView() { TranslationY = outerContent.Height };
outerContent.SetBinding(HeightRequestProperty, BindingBase.Create(static (ContentView a) => a.TranslationY, source: animation));
expanderChevron.Rotation = value ? 180 : 0;
await animation.TranslateTo(0, value ? innerContent.Height : 1, AnimDuration);
outerContent.HeightRequest = value ? innerContent.Height : 1;
isExpanded = value;
OnPropertyChanged(nameof(IsExpanded));
});
}
}
private void OnExpand(object sender, EventArgs e)
{
IsExpanded = !IsExpanded;
} Here's what it looks like when you insert the above into the .NET MAUI starter app: If required, I could refactor this as a component and place it in a fork. |
Beta Was this translation helpful? Give feedback.
-
It would be nice to be able to animate the Expander control upon expanding
More specifically:
For now the API includes a IsExpanded flag whose value changes whether only the header or the header + the content of the expander is shown.
It would be nice to add a way to add a visual animation for the transition between the "expanded" and "not expanded" state change induced by the toggling of IsExpanded property. For example adding another boolean property ShouldAnimateExpandedChanges or a method like ToggleIsExpanded providing a shouldAnimate parameter.
Beta Was this translation helpful? Give feedback.
All reactions