Xamarin.Forms Horizontal Listview Explained

The greatest advantage of using Xamarin Forms is obviously the Binding system and the viewmodels. Especially, collections of data fits perfectly with ListViews allowing views prototyping and decoupling of views and models.

Quite often you need to show List of elements in a row, perhaps with a scrolling pane. For instance, you are trying to show an horizontal list of images or buttons which are not predetermined, but changes on user inputs or remote response.

If you are getting started with Xamarin.Forms documentation really not provide any info about Horizontal ListViews and you think they can’t be done, so you start browsing the Forum and Stackoverflow, which quite often redirect you to download a component, to write Platform specific code. Things mess up quite soon.

Fortunately, your search is over. You can make Horizontal ListViews with Bindings without doing much more than write few Xaml rows of code. Let’s go understand the logic.

Horizontal ListViews in Xaml basics

First, you have to know that each element in Xaml derive from base class that has Rotation property.

  • Rotation property is used to get and set the current Rotation of the element.

First step to create an Horizontal ListView is Rotate 270 degrees (for left to right) or 90 degrees (for right to left) and the inner View element should compensate this rotation as follows:

<ListView Rotation="270" ItemsSource="{Binding Items}">
 
  
   
    <ContentView Rotation="90">
     
    
   
  
 

If you try this code you can see that dimensions are all messed up. The problem here is that listview sizes are calculated before rotation. If your list view is wider than taller you’ll probably see it floating vertically on other elements of the page. This is not the required behavior.

Let’s see how to fix layout.

Fixing Horizontal ListView Layout

The trick here is all about wrapping the ListView in a container and constraint the ListView to match conteiner bounds.

The element in Xamarin.Forms to do this is the Relative Layout.

First, we wrap the ListView in a RelativeLayout element and set the Layout Height to the desired height:

<RelativeLayout HeightRequest="60">
 <ListView Rotation="270" ItemsSource="{Binding Items}" RowHeight="60">
   ....
 

In this example we will show square images, so we’ll also set RowHeight in ListView equal to RelativeLayout Height. Note that as the ListView is rotated the ListView.RowHeight property describe how wide the element is, while RelativeLayout.HeightRequest property describe how tall the element is. Just not get confused with rotation and names.

Second, we need to tell the ListView to bind to RelativeLayout bounds. This is possible setting the RelativeLayout constraints in the child element.

 <ListView Rotation="270" ItemsSource="{Binding Items}" RowHeight="60"
 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.5, Constant=-30}"
 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=-0.5, Constant=30}"
 RelativeLayout.WidthConstraint="{ConstraintExpression Type=Constant, Constant=60}"
 RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}">
   ....
 

With XConstraint and YConstraint we adjust ListView X,Y anchors, then we set its Width (don’t forget it’s rotated so it correspond to how tall is shown) to a constant equal to parent height and we set its Height (again its shown width) to its parent width.

If you run this code now you should see the ListView much better. But probably you won’t see any element as they are now shifted out of the visible pane.

Last, indeed, we need to translate the content view on the X axis and make sure that images will fit the available viewport. Hereafter the whole code:

 <ListView Rotation="270" ItemsSource="{Binding Items}" RowHeight="60" SeparatorVisibility="None"
 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.5, Constant=-30}"
 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=-0.5, Constant=30}"
 RelativeLayout.WidthConstraint="{ConstraintExpression Type=Constant, Constant=60}"
 RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}">
  
   
    
     <ContentView Rotation="90" Padding="1" TranslationX="60">
      <Image Source="{Binding Source}" HeightRequest="58" WidthRequest="58" Aspect="AspectFill">
     
    
   
  
 

Here you are! Your Horizontal ListView for Xamarin.Forms in XAML is ready

You can now play with Rotation, Width and Height to obtained the desired effect. Just don’t forget that ListView Width and Height refers to element Width and Height and do not take in consideration that you have Rotate the element.

If you have downloaded strange components get rid of them, notwithstanding if you have written a fantastic code and you want to share just put a comment below. We are keen to know about other solutions for the Best Horizontal ListView in Xamarin.Forms.

34 pensieri riguardo “Xamarin.Forms Horizontal Listview Explained

  1. Luca buonasera,
    mi sto avvicinando al mondo Xamarin Forms e vorrei creare una pagina con il dettaglio di un immobile e sotto una image gallery; per fare questo ho trovato il tuo esempio molto interessante ma non riesco ad usarlo causa vari errori in esecuzione.
    Avresti un esempio più esteso da mostrarmi?
    Ti ringrazio..

    Luca

    "Mi piace"

  2. The above code is not working at my end. Data is not visible and also exception is thrown as below…
    Xamarin.Forms.Xaml.XamlParseException: Position 46:21. Cannot assign property “Rotation”: Property does not exists, or is not assignable, or mismatching type between value and property
    at Xamarin.Forms.Xaml.ApplyPropertiesVisitor.SetPropertyValue(Object xamlelement, XmlName propertyName, Object value, Object rootElement, INode node, HydratationContext context, IXmlLineInfo lineInfo)
    at Xamarin.Forms.Xaml.ApplyPropertiesVisitor.Visit(ValueNode node, INode parentNode)
    at Xamarin.Forms.Xaml.ValueNo

    How can i get working listview with horizontal scroll. Also how to display multiple items in that view as right now you are showing only single image.
    Please help me to solve this issue.

    Thanks

    "Mi piace"

  3. It seems that there’s a typo in the snippet. I think it should be
    ItemsSource= instead ItemSource=. Similarly with Rotation (not Rotatation).

    "Mi piace"

  4. Very well done… One question is that the scrollbar appears on the top of the list ( when scrolling in iOS) . How can you make it come at the bottom ?

    "Mi piace"

  5. I have used it for the MyWeather demo app by James Montemagno as a test …
    Here is the XAML for it… I created another String in my Weather.cs file to display how i wanted it ( DisplayDateFinal ). The only little issue is that the scrollbar appears on the top… It’s not a big issue, but will be nice if it appears on the bottom 😉

    [JsonIgnore]
    public string DisplayDateFinal
    {
    get
    {
    int hh = Convert.ToInt32(DateTime.Parse(Date).ToLocalTime().ToString(“hh”));
    string tt = DateTime.Parse(Date).ToLocalTime().ToString(“tt”);

    return hh.ToString()+” “+tt+”, “+ DateTime.Parse(Date).ToLocalTime().ToString(“dd MMM”);
    }
    }

    "Mi piace"

Lascia un commento

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.