Подтвердить что ты не робот

Горизонтальный ListView Xamarin.Forms

Можно ли создать ListView с horizontal scroll в Xamarin.Forms как изображение

ListView Horizontal

это то, что я сделал для вертикального

var myListView = new ListView
{
    ItemTemplate = new DataTemplate(typeof(ImageCell))
};
4b9b3361

Ответ 1

Да, вы технически можете. Установите Rotation на 270 (все объекты VisualElements имеют свойство поворота BindableProperty). Однако это выглядит как субоптимальное решение, так как в верхней и нижней частях есть белые пробелы, и вам нужно перетащить вид влево и вправо, чтобы увидеть все полностью.

public static readonly BindableProperty RotationProperty;
public static readonly BindableProperty RotationXProperty;
public static readonly BindableProperty RotationYProperty;

Код, приведенный выше, относится к классу VisualElement. Кодекс ниже - небольшая собственная модель.

                                              ∨∨∨                                                  
<ListView x:Name="MessagesListView" Rotation="270" ItemsSource="{Binding Items}" RowHeight="40">
  <ListView.ItemTemplate>
    <DataTemplate>
      <ViewCell>
        <ViewCell.View>
          <StackLayout>
            <!--mylayouthere-->
          </StackLayout>
        </ViewCell.View>
      </ViewCell>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

Ответ 2

Как и все остальные, No: в Xamarin.Forms отсутствует один доступный из коробки.

Однако - это не мешает кому-либо писать собственный пользовательский рендеринг для достижения такого типа управления.

Как упоминал Стефан Делкрукс, вы можете создать ScrollView, а затем StackLayout в качестве ребенка, чтобы создать тот же эффект.

Затем вам нужно реализовать: -

*), чтобы принять свойство (IEnumerable) ItemsSource, которое необходимо создать.

*), чтобы принять свойство (DataTemplate) ItemTemplate, которое необходимо создать.

*), чтобы создать экземпляр ItemTemplate, взяв конкретный элемент данных и превратив его в StackLayout. Вы также должны рассмотреть элементы, удаленные и т.д.

*) присоединить обработчики событий/жесты нажатия для выбора элемента.

*), реализующий выбранное состояние/дезактивацию других выбранных элементов.

... и т.д., чтобы получить полную реализацию.

Проблема со всем вышеизложенным заключается в том, что он подходит для относительно небольших списков элементов.

Однако, если вы ищете длинный список записей, то выше будет немного нежелательно, поскольку вы создаете все Представления.

Даже если вы задерживаете их загрузку, у вас все еще есть память для всех Представлений.

Затем это приводит к другой возможной реализации, которая касается виртуализированных элементов, что представляет собой совершенно другую историю, которую следует учитывать.

Ответ 3

Как указывалось выше, стандартного способа сделать это не существует, однако существует способ его использования с использованием стандартного подхода ListView и @MillieSmiths.

Для решения требуется несколько уровней вложенных макетов. Начиная с ListViewwe будет вращаться на 270 градусов, однако это также поворачивает наше содержимое элемента, поэтому нам нужно повернуть его на 90 градусов.

Поворот в ListView создает очень много пробелов, обертывая ListView в абсолютном макете, мы можем решить это (нам нужно дополнительное содержание в нем, чтобы исправить некоторые проблемы отсечения).

Наконец, в коде мы должны отобразить обрезку макета

Посмотрите полное решение:

<AbsoluteLayout x:Name="MessagesLayoutFrame" Padding="0" HorizontalOptions="FillAndExpand">
  <ContentView x:Name="MessagesLayoutFrameInner"  Padding="0"  HorizontalOptions="FillAndExpand">
    <ListView x:Name="MessagesListView"
              ItemsSource="{Binding Images}"
              RowHeight="240"
              VerticalOptions="Start"
              HeightRequest="240"
              WidthRequest="240"
              SeparatorVisibility="None"
              Rotation="270"
              HorizontalOptions="Center">
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <ContentView Rotation="90" Padding="12">
              <Image Source="{Binding Source}" Aspect="AspectFill" />
            </ContentView>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </ContentView>
</AbsoluteLayout>

Для кода, стоящего за нами, нам просто нужно проверить, были ли мы раньше заданы вопросы, если у нас есть, отпустите его. В основном мы выясняем, какова ширина страницы (NameGrid является контейнером полной ширины где-то в другом месте), а затем перемещает контейнер ListView по половине пробела и обрезает его другой половиной внизу)

    bool hasAppearedOnce = false;
    protected override void OnAppearing() {
        base.OnAppearing();

        if (!hasAppearedOnce) {

            hasAppearedOnce = true;
            var padding = (NameGrid.Width - MessagesListView.Height) / 2;

            MessagesListView.HeightRequest = MessagesLayoutFrame.Width;
            MessagesLayoutFrameInner.WidthRequest = MessagesLayoutFrame.Width;
            MessagesLayoutFrameInner.Padding = new Thickness(0);
            MessagesLayoutFrame.Padding = new Thickness(0);
            MessagesLayoutFrame.IsClippedToBounds = true;
            Xamarin.Forms.AbsoluteLayout.SetLayoutBounds(MessagesLayoutFrameInner, new Rectangle(0, 0 - padding, AbsoluteLayout.AutoSize, MessagesListView.Height - padding));
            MessagesLayoutFrameInner.IsClippedToBounds = true;
             // */
        } 
    }

Внимание НЕ ИСПОЛЬЗУЙТЕ <FRAMES> для перемещения и вращения макета. Он сработает на Windows Phone.

P.S Я уверен, что это может быть завершено в приятном UserControl для всех, кто будет использовать.

Ответ 4

Как и все остальные, невозможно с ListView, и я думаю, что это большой надзор со стороны Xamarin с помощью форм. Нам нужно динамически отображать объекты, управляемые данными, в большей степени, чем просто список, делающий вниз... давай, я! "

Однако в проекте Xamarin Labs есть GridView, который вы могли бы использовать. Это все еще немного грубо, и теперь люди просматривают некоторые ошибки при выборе элементов.

https://github.com/XForms/Xamarin-Forms-Labs

У кого-то, похоже, есть проблема с этой проблемой:

https://github.com/XForms/Xamarin-Forms-Labs/issues/236

Ответ 5

В отношении Xamarin Forms 2.3 CarouselView делает именно это и многое другое. Подробнее здесь.

<ContentView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
  <CarouselView ItemsSource="{Binding MyDataSource}">
    <CarouselView.ItemTemplate>
      <DataTemplate>
        <Label Text="{Binding LabelText}" />
      </DataTemplate>
    </CarouselView.ItemTemplate>
  </CarouselView>
</ContentView>

Ответ 6

Нет, нет возможности иметь горизонтальный ListView. Вы можете обернуть горизонтальный StackLayout в горизонтальном ScrollView для достижения того же визуального результата, но это не совсем то же самое, что и у вас не будет DataTemplating.

Ответ 8

Я попробовал упомянутое "вращающееся" решение, и, кроме того, это "уродливое" решение, оно также содержит несколько ограничений:

  • list view WidthRequest должен быть таким же, как HeightRequest
  • listView height height больше не работает должным образом, поскольку он становится шириной ячейки
  • verticalalign становится горизонтальным и т.д., не очень поддерживаемым.

Лучшим вариантом является создание собственного пользовательского элемента управления или, как и я, использование существующего HorizontalListView: https://www.nuget.org/packages/HorizontalListView1.1/ Этот простой в использовании. Вы можете найти исходный код и документацию здесь

Реализация:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="test.ListPage" 
    xmlns:Controls="clr-namespace:HorizontalList;assembly=HorizontalList"> 

<Controls:HorizontalListView ItemsSource="{Binding Categories}" ListOrientation="Horizontal"> 
  <Controls:HorizontalListView.ItemTemplate> 
    <DataTemplate> 
    <Label Text="{Binding Name}" /> 
    </DataTemplate> 
  </Controls:HorizontalListView.ItemTemplate> 
  </Controls:HorizontalListView>
</ContentPage>

Ответ 9

Этот пакет Nuget идеально подойдет для вашего случая. Я использовал это раньше, и мне действительно нравится это:

https://github.com/SuavePirate/DynamicStackLayout

Чтобы сделать вещи еще лучше, загрузите эти 3 пакета Nuget для загрузки, кэширования и преобразования изображений на своих фотографиях. Фотографии будут иметь форму круга, но этот нюгет имеет другие типы преобразований:

Xamarin.FFImageLoading (https://github.com/luberda-molinet/FFImageLoading/wiki/Xamarin.Forms-API)
Xamarin.FFImageLoading.Forms
Xamarin.FFImageLoading.Transformations (https://github.com/luberda-molinet/FFImageLoading/wiki/Transformations-Guide)

Вот фрагмент кода, который поможет вам начать:

<!--Add this code to the top of your page-->
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
xmlns:dynamicStackLayout="clr-namespace:SuaveControls.DynamicStackLayout;assembly=SuaveControls.DynamicStackLayout"


<!-- Here is your control inside a ScrollView. The property Photos is a list of images address (Urls)  -->

<ScrollView Orientation="Horizontal" HorizontalOptions="FillAndExpand">
    <dynamicStackLayout:DynamicStackLayout ItemsSource="{Binding Photos}" HorizontalOptions="Fill" Orientation="Horizontal" Padding="10, -0, 100, 10">
        <dynamicStackLayout:DynamicStackLayout.ItemTemplate>
            <DataTemplate>
                <StackLayout BackgroundColor="Transparent" >
                    <ffimageloading:CachedImage HorizontalOptions="Start" VerticalOptions="Center" DownsampleToViewSize="true" Aspect="AspectFit" Source="{Binding .}">
                        <ffimageloading:CachedImage.GestureRecognizers>
                            <TapGestureRecognizer Command="{Binding Path=PhotoCommand}" CommandParameter="{Binding .}" NumberOfTapsRequired="1" />
                        </ffimageloading:CachedImage.GestureRecognizers>
                        <ffimageloading:CachedImage.HeightRequest>
                            <OnPlatform x:TypeArguments="x:Double">
                                <On Platform="iOS" Value="50" />
                                <On Platform="Android" Value="60" />
                            </OnPlatform>
                        </ffimageloading:CachedImage.HeightRequest>
                        <ffimageloading:CachedImage.WidthRequest>
                            <OnPlatform x:TypeArguments="x:Double">
                                <On Platform="iOS" Value="50" />
                                <On Platform="Android" Value="60" />
                            </OnPlatform>
                        </ffimageloading:CachedImage.WidthRequest>
                        <ffimageloading:CachedImage.Transformations>
                            <fftransformations:CircleTransformation BorderHexColor="#eeeeee">
                                <fftransformations:CircleTransformation.BorderSize>
                                    <OnPlatform x:TypeArguments="x:Double">
                                        <On Platform="iOS" Value="10" />
                                        <On Platform="Android" Value="10" />
                                    </OnPlatform>
                                </fftransformations:CircleTransformation.BorderSize>
                            </fftransformations:CircleTransformation>
                        </ffimageloading:CachedImage.Transformations>
                    </ffimageloading:CachedImage>
                </StackLayout>
            </DataTemplate>
        </dynamicStackLayout:DynamicStackLayout.ItemTemplate>
    </dynamicStackLayout:DynamicStackLayout>
</ScrollView>

Я надеюсь, что это помогает :)

Ответ 10

Насколько я знаю, есть 3 способа реализовать это:

  1. Вращение (как упоминали другие ребята)
    • Больше не нужно делать этот стандартный ListView
    • ItemTemplate доступен
    • Гадкое решение!
  2. Custom Render (RecyclerView в Android и (я думаю) UICollectionView в iOS)
    • Доступна пользовательская ячейка (я уверен в Android, но не уверен в iOS)
    • Нужно больше работы и кода
  3. Grid и Horizontal ScrollView (используя горизонтальный как значение для ориентации в ScrollView)
    • Пользовательский макет доступен
    • В этом решении нет CachingStrategy, поэтому для большого списка это может привести к огромному использованию ОЗУ для вашего приложения.

Ответ 11

До выхода CollectionView вы можете использовать мой Xamarin.Forms HorizontalListView.

Она имеет:

  • Привязка к первому или среднему элементу
  • Обивка и расстояние между предметами
  • Обрабатывает действия NotifyCollectionChangedAction по добавлению, удалению и сбросу
  • Просмотр утилизации
  • RecyclerView на Android
  • UICollectionView на iOS
  • Эта реализация на самом деле очень близка с точки зрения философии и реализации к тому, что обеспечит будущее Xamarin CollectionView.

Ответ 13

В Xamarin.Forms 4.0-pre вы можете использовать CollectionView, что упрощает получение этого типа макета.

Образец:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <ListItemsLayout>
            <x:Arguments>
                <ItemsLayoutOrientation>Horizontal</ItemsLayoutOrientation>    
            </x:Arguments>
        </ListItemsLayout>
    </CollectionView.ItemsLayout>
</CollectionView>

Ответ 14

Это было решено с помощью специального класса под названием ItemsView (не путать с Xamarin ItemsView для шаблонов данных в ListView), который реализует шаблон ScrollView/StackPanel, упомянутый выше, для которого уже запрошен пример. Посмотрите код: https://gist.github.com/fonix232/b88412a976f67315f915