3

In Xamarin Forms, I want to implement a horizontal listview (like shown in the image below). Via Rotation this is possible, but the I cannot change the row width. Is there also a possibility the let the second layout start under the first one? Thanks in advance!

 <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="Recipe.Pages.SearchPage"
         Title="Search">
<ContentPage.Content>
<StackLayout Spacing="5" x:Name="layout" Orientation="Vertical" >
  <StackLayout x:Name="layoutButtons" HorizontalOptions="FillAndExpand" Orientation="Horizontal" Spacing="5" BackgroundColor="Red">
    <Button x:Name="btn1" BackgroundColor="White" Image="@drawable/scan" />
    <Button x:Name="btn2" BackgroundColor="White" Image="@drawable/menu" />
    <Button x:Name="btn3" BackgroundColor="White" Image="@drawable/search" />
  </StackLayout>
  <StackLayout x:Name="layoutList" >
    <ListView  x:Name="listView" Rotation="270" RowHeight="75" >
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <StackLayout BackgroundColor="#eee" Orientation="Vertical" >
              <StackLayout Orientation="Horizontal" >
                <Button BackgroundColor="White" Rotation="90" Image="{Binding Recipe}" />
              </StackLayout>
          </StackLayout>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </StackLayout>
 </StackLayout>
 </ContentPage.Content>
</ContentPage>

enter image description here

EDIT I also tried with a grid in the listview. Having the same issue.

 <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="Recipe.Pages.SearchPage"
         Title="Search">
<ContentPage.Content>
<StackLayout Spacing="5" x:Name="layout" Orientation="Vertical" >
  <StackLayout x:Name="layoutButtons" HorizontalOptions="FillAndExpand" Orientation="Horizontal" Spacing="5" BackgroundColor="Red">
    <Button x:Name="btn1" BackgroundColor="White" Image="@drawable/scan" />
    <Button x:Name="btn2" BackgroundColor="White" Image="@drawable/menu" />
    <Button x:Name="btn3" BackgroundColor="White" Image="@drawable/search" />
  </StackLayout>
  <StackLayout x:Name="layoutList" >
    <ListView  x:Name="listView" Rotation="270" RowHeight="75" >
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <Grid>
              <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
              </Grid.RowDefinitions>
              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="75" />
              </Grid.ColumnDefinitions>
              <Button Grid.Column="0" BackgroundColor="White" Rotation="90" Image="{Binding Recipe}" />
            </Grid>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
4
  • Try to limit Height of ListView via HeightRequest or put it inside Grid... Commented Nov 17, 2016 at 9:07
  • @EgorGromadskiy For this I tried to set WidthRequest to the ListView, but this doesn't work. Commented Nov 17, 2016 at 9:24
  • Have you find any solution for this? Commented Jan 6, 2017 at 13:50
  • @PravinD No I changed my layout Commented Jan 9, 2017 at 7:59

3 Answers 3

6

I have also facing the same issue. I used below xaml code to manage the height and width of ListView.

<?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="VCRoom.HorizontalScroll">
  <ContentPage.Content >
    <RelativeLayout>
      <ListView x:Name="TestListView"
                RowHeight="80"
                Rotation="270"
                RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.5, Constant=-40}"
                RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=-0.5, Constant=40}"
                RelativeLayout.WidthConstraint="{ConstraintExpression Type=Constant, Constant=80}"
                RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}"
                >
      </ListView>
    </RelativeLayout>
  </ContentPage.Content>
</ContentPage>

Change RowHeight and Constant in XConstraint and YConstraint to manage Width and height of horizontal ListView accordingly.

Just for reference Below is custom cell I used to populate ListView items. I displayed vertical labels in each list item.

<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="VCRoom.TestCell">
  <ViewCell.View>

      <StackLayout Orientation="Horizontal" HorizontalOptions="End" VerticalOptions ="Center">
        <Label Rotation="90" Text="{Binding Day}"  TextColor="#000000" HorizontalOptions="StartAndExpand" VerticalOptions="Start"/>
        <Label Rotation="90" Text="{Binding mDate}" TextColor="#000000" HorizontalOptions="StartAndExpand" VerticalOptions="Start"/>
      </StackLayout>

  </ViewCell.View>
</ViewCell>

Hope this will help future users.

Sign up to request clarification or add additional context in comments.

Comments

1

The best solution that i found to resolve this problem is making a CustomScrollView with properties from Listview, like is showed in the tutorial from the Fabio Cozzolino.

Pay attention that he has a updated version in the comments.

He created a custom scrollview:

public class TLScrollView : ScrollView
{   public static readonly BindableProperty ItemsSourceProperty =
        BindableProperty.Create("ItemsSource", typeof(IEnumerable), typeof(CustomScrollView), default(IEnumerable),
                                BindingMode.Default, null, new BindableProperty.BindingPropertyChangedDelegate(HandleBindingPropertyChangedDelegate));

    private static object HandleBindingPropertyChangedDelegate(BindableObject bindable, object value)
    {
        throw new NotImplementedException();
    }

    public IEnumerable ItemsSource
    {
        get { return (IEnumerable)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }

    public static readonly BindableProperty ItemTemplateProperty =
        BindableProperty.Create("ItemTemplate", typeof(DataTemplate), typeof(CustomScrollView), default(DataTemplate));

    public DataTemplate ItemTemplate
    {
        get { return (DataTemplate)GetValue(ItemTemplateProperty); }
        set { SetValue(ItemTemplateProperty, value); }
    }

    public event EventHandler<ItemTappedEventArgs> ItemSelected;

    public static readonly BindableProperty SelectedCommandProperty =
        BindableProperty.Create("SelectedCommand", typeof(ICommand), typeof(CustomScrollView), null);

    public ICommand SelectedCommand
    {
        get { return (ICommand)GetValue(SelectedCommandProperty); }
        set { SetValue(SelectedCommandProperty, value); }
    }

    public static readonly BindableProperty SelectedCommandParameterProperty =
        BindableProperty.Create("SelectedCommandParameter", typeof(object), typeof(CustomScrollView), null);

    public object SelectedCommandParameter
    {
        get { return GetValue(SelectedCommandParameterProperty); }
        set { SetValue(SelectedCommandParameterProperty, value); }
    }

    static void HandleBindingPropertyChangedDelegate(BindableObject bindable, object oldValue, object newValue)
    {
        var isOldObservable = oldValue?.GetType().GetTypeInfo().ImplementedInterfaces.Any(i => i == typeof(INotifyCollectionChanged));
        var isNewObservable = newValue?.GetType().GetTypeInfo().ImplementedInterfaces.Any(i => i == typeof(INotifyCollectionChanged));

        var tl = (CustomScrollView)bindable;
        if (isOldObservable.GetValueOrDefault(false))
        {
            ((INotifyCollectionChanged)oldValue).CollectionChanged -= tl.HandleCollectionChanged;
        }

        if (isNewObservable.GetValueOrDefault(false))
        {
            ((INotifyCollectionChanged)newValue).CollectionChanged += tl.HandleCollectionChanged;
        }

        if (oldValue != newValue)
        {
            tl.Render();
        }
    }

    private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        Render();
    }
}

Created a method to render the scrollview:

public void Render ()
{  if (ItemTemplate == null || ItemsSource == null)
        {
            Content = null;
            return;
        }

        var layout = new StackLayout();
        layout.Orientation = Orientation == ScrollOrientation.Vertical ? StackOrientation.Vertical : StackOrientation.Horizontal;

        foreach (var item in ItemsSource)
        {
            var command = SelectedCommand ?? new Command((obj) =>
            {
                var args = new ItemTappedEventArgs(ItemsSource, item);
                ItemSelected?.Invoke(this, args);
            });
            var commandParameter = SelectedCommandParameter ?? item;

            var viewCell = ItemTemplate.CreateContent() as ViewCell;
            viewCell.View.BindingContext = item;
            viewCell.View.GestureRecognizers.Add(new TapGestureRecognizer
            {
                Command = command,
                CommandParameter = commandParameter,
                NumberOfTapsRequired = 1
            });

            layout.Children.Add(viewCell.View);
        }

        Content = layout; }

Then, a customRenderer to each platform (Here iOS):

[assembly: ExportRenderer(typeof(TLScrollView), typeof(TLScrollViewRenderer))]

namespace TitiusLabs.Forms.iOS.Controls
{  
class CustomScrollViewRenderer : ScrollViewRenderer
{
    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);

        var element = e.NewElement as CustomScrollView;
        element?.Render();
    }
} }

Comments

0

You can use the FlowListView plugin to archive horizontal listview easily on xamarin forms.

NuGet - DLToolkit.Forms.Controls.FlowListView

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.