Halvard
Halvard

Reputation: 4001

Xamarin.Forms: ListView inside StackLayout: How to set height?

In a ContentPage I have a ListView inside a StackLayout inside a ScrollView. The ListView is populated (ItemSource is set) in the ContentPage when OnAppearing gets called and I can see that the list is populated in the emulator. The StackLayouts orientation is Vertical and below the ListView I have a Button.

My problem is that no matter how many elements the ListView has, it gets the height of 53.33. I would like the height of the ListView to match the total height of the items in it. By setting HeightRequest I can set the height of the ListView to anything I want, but since I do not know the height of the items inside the ListView the result is most often that the distance to the button below it is incorrect and therefore looks ugly. I have tried to set VerticalOptions on both the ListView and the StackLayout to Startand other settings, but this does not change the height from 53.33 (and if I try to combine using HeightRequest and Start it turns out that HeightRequest wins out).

How can I solve this?

(please excuse the cross posting from Xamarin forum)

Upvotes: 42

Views: 51556

Answers (8)

mehrandvd
mehrandvd

Reputation: 9116

With the new BindableLayout feature in Xamarin Forms 3.5 you can easily use the ItemsSource on StackPanel.

So, basically you can write something like this:

<StackLayout BindableLayout.ItemsSource="{Binding list}">
    <BindableLayout.ItemTemplate>
        <DataTemplate>
            ...
        </DataTemplate>
    </BindableLayout.ItemTemplate>
</StackLayout>

You can read more about it here: https://blog.xamarin.com/xamarin-forms-3-5-a-little-bindable-love/

Upvotes: 25

The accepted answer wasn't applicable to my situation, where my ListView might be longer then the length of the display, hence it needs be placed within a ScrollView, which brings back the empty space.

They way I solved this, was to have top level StackLayout and then place the ListView in an immediate ScrollView, like the following XAML:

<?xml version="1.0" encoding="utf-8" ?>
<local:ContentPage>
    <StackLayout x:Name="entirePage">
        <ScrollView VerticalOptions="FillAndExpand"
            Orientation="Vertical">
            <ListView x:Name="listView" ItemsSource="{Binding Items}"
                Margin="0">
                <!-- ListView Stuff -->
            </ListView>
        </ScrollView>
    </StackLayout><!--entirePage-->
</local:ContentPage >

Upvotes: 0

Ian Warburton
Ian Warburton

Reputation: 15726

On Android, my table created in code was leaving gaps above and below it.

This fixed it...

HeightRequest="1000000"

I think I have the hackiest solution.

Upvotes: 0

BRass
BRass

Reputation: 3838

I had a similar struggle, with a slightly different solution. First, setting a RowHeight on the ListView seemed to be pivotal. Second, I was running into a binding + timing issue. If the ListView was displayed and had no contents, it was set to a default height (showing the empty space). If I moved away from this page and came back, the size was fine.

So my approach was to bind the ListView's visibility to the presence (or lack of) something being bound to. Then when data came back, the ListView became visible and had the proper size.

<ListView x:Name="lvSettlements" ItemsSource="{Binding RecentSettlements}"  VerticalOptions="FillAndExpand" RowHeight="25" IsVisible="{Binding RecentSettlements, Converter={StaticResource nullConverter}}">
...SNIP...
</ListView>

Upvotes: 1

Vinod Kumar
Vinod Kumar

Reputation: 137

Below code worked for me,

protected override void OnAppearing()
{
base.OnAppearing(); 
listViewOrderCloths.HeightRequest = model.ListOrderedCloths.Count*100)/2 ;
}

Upvotes: 8

Marcio Martins
Marcio Martins

Reputation: 340

I had the same problem, and this was the only thing I did that solved for me (in XAML):

<StackLayout Orientation="Vertical"
             VerticalOptions="Fill"
             HorizontalOptions="StartAndExpand">
    <ListView VerticalOptions="FillAndExpand"
              RowHeight="<some row height>">
    </ListView>
</StackLayout>

Hope it works!

Upvotes: 9

Norbor Illig
Norbor Illig

Reputation: 658

I ran into the same problem, and for me this worked like a charm:

listView.HasUnevenRows = true;

(http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/listview/#Display_Rows_with_Variable_Heights)

Upvotes: 18

Halvard
Halvard

Reputation: 4001

The solution in my case was to put the ListView inside a StackLayout and then put that StackLayout inside the main StackLayout. Then I could set the VerticalOptions = LayoutOptions.FillAndExpand on the inner StackLayout (the one containing the ListView) with the result that the ListView got the space it needed (which of course varies depending on the data).

Here is the main code:

listView.ItemsSource = alternativeCells;
listView.ItemSelected += ListViewOnItemSelected;
var listStackLayout = new StackLayout
{
    VerticalOptions = LayoutOptions.FillAndExpand,
    Orientation = StackOrientation.Vertical
};
listStackLayout.Children.Add(listView);
_stackLayout.Children.Add(listStackLayout);

As you see, I added a new StackLayout with the only purpose of putting the ListView inside it. Then I put that listStackLayout inside the main _stackLayout.

See the post on this Xamarin forum post for more information

Upvotes: 20

Related Questions