问题
I'm trying to implement a kind of collapsable StackLayout. Every tine the user clicks the button, it expands or collapse the stacklayout to show/hide more details.
I was able to achieve more/less this with the code below, but it doesn't look right and the effect isn't great, because it grows immediately and I'm applying the effect to other element.
Do you have any suggestions to do this, I'm using xamarin Forms?
XAML
<?xml version="1.0" encoding="utf-8" ?>
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Sample.MyStackLayout" >
<StackLayout x:Name="TopLayout">
<StackLayout Orientation="Horizontal">
<Label Text="some text" VerticalOptions="Center" HorizontalOptions="StartAndExpand" />
<Label Text="123" VerticalOptions="Center" HorizontalOptions="End" FontSize="Large" />
</StackLayout>
<BoxView Color="Black" HeightRequest="1" />
<StackLayout Orientation="Horizontal">
<Label Text="some text" VerticalOptions="Center" HorizontalOptions="StartAndExpand" />
<Label Text="123" VerticalOptions="Center" HorizontalOptions="End" FontSize="Large" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="some text" VerticalOptions="Center" HorizontalOptions="StartAndExpand" />
<Label Text="123" VerticalOptions="Center" HorizontalOptions="End" FontSize="Large" />
</StackLayout>
<Button x:Name="btn" Text="Button" Clicked="btnClicked" />
</StackLayout>
<StackLayout x:Name="MoreDetails" IsVisible="False">
<Label Text="some text 1"></Label>
<Label Text="some text 2"></Label>
<Label Text="some text 3"></Label>
<Label Text="some text 4"></Label>
<Label Text="some text 5"></Label>
<Label Text="some text 6"></Label>
<Label Text="some text 7"></Label>
<Label Text="some text 8"></Label>
</StackLayout>
</StackLayout>
Code
public AccountInfo()
{
InitializeComponent();
}
bool isExpanded = false;
protected async void btnClicked(object sender, EventArgs e)
{
if (isExpanded)
{
await MoreDetails.FadeTo(0);
MoreDetails.IsVisible = !isExpanded;
}
else
{
MoreDetails.IsVisible = !isExpanded;
await MoreDetails.FadeTo(1);
}
isExpanded = !isExpanded;
}
回答1:
You can create a Custom control that does this for you. If you create an 'ExpandableView' Content View with Xaml like:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MyProject.CustomControls.ExpandableView">
<StackLayout x:Name="Layout" Orientation="Vertical" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout x:Name="SummaryRegion"/>
<StackLayout x:Name="DetailsRegion" IsVisible="False"/>
</StackLayout>
</ContentView>
And wire up the .cs class like so:
public partial class ExpandableView: ContentView
{
private TapGestureRecognizer _tapRecogniser;
private StackLayout _summary;
private StackLayout _details;
public ExpandableView()
{
InitializeComponent();
InitializeGuestureRecognizer();
SubscribeToGuestureHandler();
}
private void InitializeGuestureRecognizer()
{
_tapRecogniser= new TapGestureRecognizer();
SummaryRegion.GestureRecognizers.Add(_tapRecogniser);
}
private void SubscribeToGuestureHandler()
{
_tapRecogniser.Tapped += TapRecogniser_Tapped;
}
public virtual StackLayout Summary
{
get { return _summary; }
set
{
_summary = value;
SummaryRegion.Children.Add(_summary);
OnPropertyChanged();
}
}
public virtual StackLayout Details
{
get { return _details; }
set
{
_details = value;
DetailsRegion.Children.Add(_details);
OnPropertyChanged();
}
}
private void TapRecogniser_Tapped(object sender, EventArgs e)
{
if (DetailsRegion.IsVisible)
{
DetailsRegion.IsVisible = false;
}
else
{
DetailsRegion.IsVisible = true;
}
}
And define it in your xaml like so:
<CustomControls:ExpandableView>
<CustomControls:ExpandableView.Summary>
<StackLayout>
YOUR STUFF HERE
</StackLayout>
</CustomControls:ExpandableView.Summary>
<CustomControls:ExpandableView.Details>
<StackLayout>
YOUR STUFF HERE
</StackLayout>
</CustomControls:ExpandableView.Details>
</CustomControls:ExpandableView>
Where CustomControls is the reference to namespace where the ExpandableView exists.
You can expand this further by adding things such as animations on expand, highlight the 'Summary Region' when expanded etc...
回答2:
Wrap your everything but MoreDetails to another stack layout and name it "TopLayout"
void ShowMore(){
TopLayout.TranslateTo(0, -TopLayout.Bounds.Height, 300, Easing.Linear);
MoreDetails.LayoutTo(new Rectangle(0, 0, MoreDetails.Bounds.Width, MoreDetails.Bounds.Height + TopLayout.Bounds.Height), 300, Easing.Linear);
}
void ShowLess(){
TopLayout.TranslateTo(0, 0, 300, Easing.Linear);
MoreDetails.LayoutTo(new Rectangle(0, MoreDetails.Bounds.Height, MoreDetails.Bounds.Width, MoreDetails.Bounds.Height - MoreDetails.Bounds.Height), 300, Easing.Linear);
}
100 - here is your displacement value
As a bonus:
MoreLessImage.RotateXTo(180, Duration, TargetEasing);
you can morph your button like this to animate ShowMore/ShowLess image
来源:https://stackoverflow.com/questions/39620775/xamarin-forms-collapsable-stacklayout