Forum Xamarin.Forms

ListView inside StackLayout: a height problem

2»

Posts

  • LuisMatosLuisMatos USMember ✭✭

    @batmaci said:

    for sure it works for one device but when you actually try your solution on a bigger screen or smaller screen, you may get not expected view because you hardcode the size. This post is made for dynamic sizing. So it can adapt based on screen size of the device.

    I'll check what it says, likewise thanks for the contribution

  • ajmenaajmena ESMember ✭✭

    Hello.
    Is there any solution for this?
    I tried calculating the HeightRequest using the font size of the device.

    double SizeLabel = Device.GetNamedSize(NamedSize.Default, typeof(Label));
    double SizeCell = Device.GetNamedSize(NamedSize.Default, typeof(Cell));
    double SizeRow = (SizeCell / SizeLabel) * 17.327;
    MyListView.HeightRequest = (Items.Count > 0) ? (NumberOfRows * SizeRow * Items.Count) : 0;
    

    But in some devices I'm not obtaining a good result.
    Any ideas?

  • LyndonHugheyLyndonHughey USUniversity ✭✭✭

    I've just spent the last hour debugging a listview scenario that I've used before without issue. I ended up patching up the issue by providing a height request based on the height of the rows (by adding up the grid row heighrequests) and the number of items. I know this is a very fragile "solution", but hopefully I will come back to this at a later date.

  • NickKovalskyNickKovalsky USMember ✭✭✭

    You can check an example for xamarin evolve (https://github.com/xamarinhq/app-evolve) where they do exactly this, updating the heightrequest with a row quantity calculated height. Doesn't look fragile tbh.
    Wouldn't work for uneven rows tho.

  • ankitsejwalankitsejwal USMember
    edited May 2017

    Hey Guys nothing worked for me, eventually had success by setting MinimumHeightRequest property. See if works for you aswell.

    >     <ListView x:Name="list"   
    >       SeparatorColor="#DDD"   
    >       MinimumHeightRequest="180">
    
  • artemoniksartemoniks RUMember ✭✭

    @maxx313, Excellent!

    I would added a check on null:

        private void BuildLayout()
        {
            Children.Clear();
         
    

    if(ItemsSource == null)
    return;

            foreach (var item in ItemsSource)
            {
                var view = (View)ItemTemplate.CreateContent();
                view.BindingContext = item;
                Children.Add(view);
            }
        }
    
  • BuddhimaKudagamaBuddhimaKudagama USMember ✭✭

    I also faced to this issue, The solution is we have to set the Height of the list view according to the height of number of rows manually in code behind.
    Below link describes how I did fix it...
    https://xamarinsharp.com/2017/05/16/listview-height-issue-in-xamarin-forms-how-to-solve-it/

  • BuddhimaKudagamaBuddhimaKudagama USMember ✭✭

    And also I have tried to calculate the height using MVVM when changing the Item source of the List View. It also became successful.

    And I wrote an article that how to do it. and the article consists of my code.

    https://xamarinsharp.com/2017/05/20/xamarin-forms-listview-height-change-dynamically-using-mvvm-and-also-solve-empty-space-issue/

  • MarkCouvarasMarkCouvaras GBMember

    @maxx313 do we have to make a renderer in each platform to use it?

  • MarkCouvarasMarkCouvaras GBMember

    @maxx313 I used the below code and it is blank?

    <controls:StackLayoutList ItemsSource="{Binding MyData}">
        <controls:StackLayoutList.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Grid Padding="10">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <Label Text="{Binding Name}" FontAttributes="Bold" TextColor="Teal" FontSize="21" />
                        <Label Grid.Row="1" Text="{Binding Age}" TextColor="Teal" FontSize="15"/>
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </controls:StackLayoutList.ItemTemplate>
    </controls:StackLayoutList>
    
  • maxx313maxx313 DEMember ✭✭

    @MarkCouvaras said:
    @maxx313 do we have to make a renderer in each platform to use it?

    No, you don't need a custom renderer.

    @MarkCouvaras said:
    @maxx313 I used the below code and it is blank?

    <controls:StackLayoutList ItemsSource="{Binding MyData}">
        <controls:StackLayoutList.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Grid Padding="10">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <Label Text="{Binding Name}" FontAttributes="Bold" TextColor="Teal" FontSize="21" />
                        <Label Grid.Row="1" Text="{Binding Age}" TextColor="Teal" FontSize="15"/>
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </controls:StackLayoutList.ItemTemplate>
    </controls:StackLayoutList>
    

    Remove the ViewCell from the template, it has no use there and maybe is even the reason why the view stays blank.
    The code should work if the binding is set up properly, and the source contains data.

  • TathagataBasuTathagataBasu INMember ✭✭

    Hi All,

    I have a nice and simple solution for that. An Absolute layout saves my day. You can select Relative layout as well.

    <AbsoluteLayout>
        <ScrollView AbsoluteLayout.LayoutBounds="0,0,1,1" AbsoluteLayout.LayoutFlags="All">
          <StackLayout VerticalOptions="Fill">
            <ListView x:Name="lvChapel" HasUnevenRows="True" IsPullToRefreshEnabled="True" Refreshing="lvChapelRefreshing">
                <!-- your code ; ItemTemplate etc... -->
            </ListView>
          </StackLayout>
        </ScrollView>
      </AbsoluteLayout>
    

    Hope that solution helps... :)

  • SethSharpSethSharp USMember

    @BuddhimaKudagama said:
    And also I have tried to calculate the height using MVVM when changing the Item source of the List View. It also became successful.

    And I wrote an article that how to do it. and the article consists of my code.

    https://xamarinsharp.com/2017/05/20/xamarin-forms-listview-height-change-dynamically-using-mvvm-and-also-solve-empty-space-issue/

    This works very well. Thanks for posting.

  • BuddhimaKudagamaBuddhimaKudagama USMember ✭✭

    @SethSharp said:

    @BuddhimaKudagama said:
    And also I have tried to calculate the height using MVVM when changing the Item source of the List View. It also became successful.

    And I wrote an article that how to do it. and the article consists of my code.

    https://xamarinsharp.com/2017/05/20/xamarin-forms-listview-height-change-dynamically-using-mvvm-and-also-solve-empty-space-issue/

    This works very well. Thanks for posting.

    Happy to hear that.

  • MarkCouvarasMarkCouvaras GBMember

    @maxx313 sorry it took me so long to reply. Just wanted to say thank you for your advice it worked perfectly

  • VadymStetsyukVadymStetsyuk USMember

    @maxx313 oh my Gosh, amazing solution. Thank u very much!

  • @RobsonGilli said:
    listView.HasUnevenRows = true;

    It worked for me! Thx!

  • ShubhraPandeyShubhraPandey USMember ✭✭

    @BuddhimaKudagama said:
    I also faced to this issue, The solution is we have to set the Height of the list view according to the height of number of rows manually in code behind.
    Below link describes how I did fix it...
    https://xamarinsharp.com/2017/05/16/listview-height-issue-in-xamarin-forms-how-to-solve-it/

    Thanks for sharing link. It works perfectly!!

  • swastiswasti INMember ✭✭

    @maxx313 StackLayout is not refreshes on add elements in Item source

  • swastiswasti INMember ✭✭

    @maxx313 StackLayout is not refreshing on adding elements in Observable list binded to Item source

  • DanishAliDanishAli USMember

    if data set are overlapping simply change the listview height as : RowHeight="50"

  • TinPTBTinPTB USMember

    HasUnevenRows="True"

  • JassimRahmaJassimRahma USMember ✭✭✭✭

    i have the same problem. Listview is not taking the whole height as you can see in the attached (see marked with RED)

    Here is my XAML:

    <?xml version="1.0" encoding="UTF-8"?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="Zeera.ZeeraCategory"
        ControlTemplate="{StaticResource MainPageTemplate}">
        <ContentPage.Content>
            <StackLayout VerticalOptions="FillAndExpand" Spacing="0" Padding="5">
              <ListView x:Name="listViewCategory" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" HasUnevenRows="true" ItemTapped="OnTapped" IsVisible="false">
                <ListView.ItemTemplate>
                  <DataTemplate>
                    <ViewCell>
                        <Image Margin="10" Aspect="AspectFill" HorizontalOptions="FillAndExpand" Source="{Binding item_image}" />
                    </ViewCell>
                  </DataTemplate>
                </ListView.ItemTemplate>
              </ListView>
              <ActivityIndicator x:Name="loadingCategory" VerticalOptions="Center" HorizontalOptions="Center" AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1" Color="Blue" />
            </StackLayout>
        </ContentPage.Content>
    </ContentPage>
    

  • TeooTeoo GRMember

    Just download flowListView package in the last version and use the field called RowHeight. This Xamarin software is just a piece of sh**t without using packages .....

  • ScrollView is already supported in ListView. You don't need to add it more.

    When your data in ListView still have space enough to show on the page, ScrollView cannot move.
    But if your data in ListView is overloaded on page, ScrollView can move UP and Down.

    Goodluck! :)

  • VladisVladis USMember ✭✭
    edited December 2017

    Hey all,

    If your need is to just add a few elements to the bottom or top of your list so that it scrolls altogether, you can accomplish this using the footer and header properties. No need to measure out the heights. Data bindings work as well.

    Example below (done in code) where I have a list view made of many custom templates (using a template selector). That part of the code however is omitted:

    `

            aList= new ListView();
            aList.HasUnevenRows = true;
            aList.ItemTemplate = new ViewTemplating.aListViewTemplateSelector();
            aList.SeparatorColor = (Color)App.Current.Resources["BACKGROUND_COLOR"];
            aList.Margin = new Thickness(10, 0);
    
            aList.Footer = new StackLayout
            {
                VerticalOptions = LayoutOptions.FillAndExpand,
                Children = {
                    generalCommentsLabel,
                    generalComments,
                    new StackLayout
                    {
                        Margin = new Thickness(0,0,0,10),
                        Orientation = StackOrientation.Horizontal,
                        Children =
                        {
                            mileageSumLabel,
                            odometerMileageSum
                        },
                    },
                }
            };
          Content = aList;
    

    `

  • Gergely_BalogGergely_Balog USMember

    Hey all,

    I have tested different options in this thread now, and the following worked for me both in iOS and Android (I had issues in iOS with a weird bounce at the bottom of the page. The last few items simply were outside of the viewport of the screen)

    • ListView inside StackLayout inside AbsoluteLayout.
    • I did not need spacing 0 or setting setting manual heights. I have uneven rows.
    • I used an absolutelayout because I had a background image
    • I load data dynamically from an async method fired off in OnAppearing.

    XAML:

    <AbsoluteLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
      <Image Source="background" AbsoluteLayout.LayoutBounds="0,0,1,1" 
    AbsoluteLayout.LayoutFlags="All" Aspect="AspectFill"/>
      <StackLayout 
            HorizontalOptions="FillAndExpand" 
            VerticalOptions="FillAndExpand" 
            BackgroundColor="Transparent"
            AutomationId="MessagesStackLayout" 
            AbsoluteLayout.LayoutBounds="0,0,1,1" 
            AbsoluteLayout.LayoutFlags="All">
        <StackLayout.Margin>
          <!-- IOS X top hardware thing obscures top of page otherwise -->
          <OnPlatform x:TypeArguments="Thickness" iOS="15,44,15,0" />
        </StackLayout.Margin>
        <Grid Padding="5">
          <!-- Other content above the listview-->
        </Grid>
    <ListView HasUnevenRows="True" ItemsSource="{Binding Data}" SeparatorVisibility="None"
     BackgroundColor="Transparent" VerticalOptions="FillAndExpand">
          <ListView.ItemTemplate>
            <DataTemplate>
              <ViewCell >
                <!--Uneven viewCell content-->
              </ViewCell>
            </DataTemplate>
          </ListView.ItemTemplate>
        </ListView>
      </StackLayout>
    </AbsoluteLayout>
    
    
  • karlingenkarlingen Member ✭✭
    edited August 2018

    @maxx313 said:
    If you want to nest a ListView inside another scrollable view and calculate the exact height of it, better don't use a ListView at all. Instead use a StackLayout with templated items like the following:
    `
    public class StackLayoutList : StackLayout
    {

        public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create("ItemsSource", typeof(IList), typeof(StackLayoutList), propertyChanged: OnItemsSourceChanged);
    
        public IList ItemsSource
        {
            get { return (IList)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }
    
        public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create("ItemTemplate", typeof(DataTemplate), typeof(StackLayoutList), propertyChanged: OnItemTemplateChanged);
    
        public DataTemplate ItemTemplate
        {
            get { return (DataTemplate)GetValue(ItemTemplateProperty); }
            set { SetValue(ItemTemplateProperty, value); }
        }
    
        private static void OnItemTemplateChanged(BindableObject pObj, object pOldVal, object pNewVal)
        {
            var layout = pObj as StackLayoutList;
    
            if (layout != null && layout.ItemsSource != null)
                layout.BuildLayout();
        }
    
        private static void OnItemsSourceChanged(BindableObject pObj, object pOldVal, object pNewVal)
        {
            var layout = pObj as StackLayoutList;
    
            if (layout != null && layout.ItemTemplate != null)
                layout.BuildLayout();
        }
    
        private void BuildLayout()
        {
            Children.Clear();
            
            foreach (var item in ItemsSource)
            {
                var view = (View)ItemTemplate.CreateContent();
                view.BindingContext = item;
                Children.Add(view);
            }
        }
    }
    

    `

    I had to add a null check on foreach (var item in ItemsSource) or Prism Navigation would give me a hard time.

  • abdalrhmanabdalrhman Member ✭✭

    <ListView VerticalScrollBarVisibility="ScrollBarVisibility.Never"
    HorizontalScrollBarVisibility="ScrollBarVisibility.Never"

    I Am see This in here

    https://blog.verslu.is/xamarin/xamarin-forms-xamarin/scrollbars-listview-scrollbarvisibility/

  • For me this was the fast and clean solution:

    private void ListView_ItemAppearing(object sender, ItemVisibilityEventArgs e)
    {
    if ((sender as ListView).ItemsSource != null)
    (sender as ListView).HeightRequest = ((sender as ListView).ItemsSource as ObservableCollection).Count * (sender as ListView).RowHeight;
    }

  • vinothswamivinothswami Member ✭✭✭
    edited July 2019

    <Grid.RowDefinitions>

                            <RowDefinition Height="30"></RowDefinition>
    
                            <RowDefinition Height="30"></RowDefinition>
    
                            <RowDefinition Height="1"></RowDefinition>
    
                            <RowDefinition Height="40"></RowDefinition>
    
                        </Grid.RowDefinitions>
    

    you have to hard code like this, then the height will take as mentioned otherwise it will take default cell size. :o

  • HamittirpanHamittirpan Member ✭✭✭✭

    @RobsonGilli said:
    listView.HasUnevenRows = true;

    Had the same problem. you solved ıt.

    Thank you so much !

  • I had the same problem now, solved with this
    <StackLayout x:Name="StackLayoutDetalhesTreino" HeightRequest="{Binding Path=Height, Source={x:Reference StackLayoutDetalhesTreino}}"

    I tried to force stacklayout height taking her own height, it worked for me

  • Try to set listview out of the SL but set in grid. its work for me.
    < Grid x:Name="masterGrid" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All" ColumnSpacing="1" RowSpacing="1" > < Grid.RowDefinitions>
    < RowDefinition Height="50"/>< RowDefinition Height="*"/>< RowDefinition Height="auto"/>
    < /Grid.RowDefinitions>< StackLayout Grid.Row="0">[your extra code]< /stacklayout>< Listview Grid.Row="1" VerticalOptions="FillAndExpand" />< StackLayout Grid.Row="2">
    [your extra code]
    < /stacklayout>
    < /grid>
    Try This one. i ts work for me

  • Mattia541993Mattia541993 Member ✭✭

    This solution worked for me only putting the listView inside a StackLayout (even without options)..

    @LuisMatos said:
    The solution for me was to calculate the total height of my rows by the amount of items from the source and binding this property. Example:

    string heightList;
    int heightRowsList = 90;
    
    public string HeightList 
    { 
      get 
      { 
          heightList = (Items.Count * heightRowsList).ToString(); 
          return heightList; 
      } 
    }
    

    And in my xaml looks like this:

        <ListView x:Name="ItemsList"  HasUnevenRows="True" 
              ItemsSource="{Binding Items}" 
              HeightRequest="{Binding HeightList}"></ListView>
    
  • FadiHaniFadiHani USMember ✭✭

    Instead of using a ListView inside a StackView I ended up using a StackView inside another StackView. Could use templates using the BindableLayout.ItemsSource.

    See this answer which helped me.

    Code:

    <StackLayout BindableLayout.ItemsSource="{Binding list}">
        <BindableLayout.ItemTemplate>
            <DataTemplate>
                ...
            </DataTemplate>
        </BindableLayout.ItemTemplate>
    </StackLayout>
    
Sign In or Register to comment.