How can I animate the height of StackLayout (expand and collapse)?
I've tried Animate
extension method, but it looks like it has a bug:
public class App : Application
{
public App()
{
var stackLayout = new StackLayout
{
BackgroundColor = Color.Red.MultiplyAlpha(0.25d),
VerticalOptions = LayoutOptions.Start,
Children =
{
new BoxView{ Color = Color.Red, HorizontalOptions = LayoutOptions.FillAndExpand, HeightRequest = 50 },
new BoxView{ Color = Color.Blue, HorizontalOptions = LayoutOptions.FillAndExpand, HeightRequest = 70 },
new BoxView{ Color = Color.Olive, HorizontalOptions = LayoutOptions.FillAndExpand, HeightRequest = 40 },
}
};
double calculatedHeight = 0f;
stackLayout.SizeChanged += (sender, e) =>
{
if (Math.Abs(calculatedHeight) < 0.0001d)
{
calculatedHeight = stackLayout.Height;
}
};
var button = new Button
{
VerticalOptions = LayoutOptions.Start,
Text = "Hide",
};
var page = new ContentPage
{
Content = new StackLayout
{
Children = { stackLayout, button }
}
};
button.Command = new Command(() =>
{
var animate = new Animation(d => stackLayout.HeightRequest = d, calculatedHeight, 0);
animate.Commit(stackLayout, "BarGraph", 16, 3500);
});
MainPage = page;
}
}
Adding ForceLayout
did nothing.
Also I've tried animate the height of RowDefinition
, but it doesn't work too:
public class App : Application
{
public App()
{
var stackLayout = new StackLayout
{
BackgroundColor = Color.Red.MultiplyAlpha(0.25d),
VerticalOptions = LayoutOptions.Start,
Children =
{
new BoxView{ Color = Color.Red, HorizontalOptions = LayoutOptions.FillAndExpand, HeightRequest = 50 },
new BoxView{ Color = Color.Blue, HorizontalOptions = LayoutOptions.FillAndExpand, HeightRequest = 70 },
new BoxView{ Color = Color.Olive, HorizontalOptions = LayoutOptions.FillAndExpand, HeightRequest = 40 },
}
};
var button = new Button
{
VerticalOptions = LayoutOptions.Start,
Text = "Hide",
};
var grid = new Grid { };
var stackLayoutRow = new RowDefinition { Height = 172 };
grid.RowDefinitions = new RowDefinitionCollection
{
stackLayoutRow,
new RowDefinition { Height = GridLength.Auto }
};
grid.Children.Add(stackLayout, 0, 0);
grid.Children.Add(button, 0, 1);
Animation animation;
button.Command = new Command(() =>
{
if (stackLayoutRow.Height.Value < 172)
{
Debug.WriteLine("Show");
animation = new Animation(
callback: (d) =>
{
stackLayoutRow.Height = Clamp(d, 0, double.MaxValue);
},
start: stackLayoutRow.Height.Value,
end: 172,
easing: Easing.Linear,
finished: () => animation = null);
animation.Commit(owner: grid, name: "AnimationTag", rate: 16, length: 1000);
}
else
{
Debug.WriteLine("Hide");
animation = new Animation(
callback: (d) =>
{
stackLayoutRow.Height = Clamp(d, 0, double.MaxValue);
},
start: 172,
end: 0,
easing: Easing.Linear,
finished: () => animation = null);
animation.Commit(owner: grid, name: "AnimationTag", rate: 16, length: 1000);
}
});
var page = new ContentPage
{
Content = grid
};
MainPage = page;
}
private static double Clamp(double value, double minValue, double maxValue)
{
if (value < minValue)
{
return minValue;
}
if (value > maxValue)
{
return maxValue;
}
return value;
}
}
I'm using Xamarin.Forms 2.1.0