c# listview xamarin xamarin.forms

c# - Horizontal ListView Xamarin.Forms



(11)

A partir de Xamarin Forms 2.3, CarouselView hace precisamente eso y más. Lea más here .

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

Es una forma de crear ListView con horizontal scroll en Xamarin.Forms como imagen

esto es lo que he hecho para vertical

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


Como han dicho los demás, no es posible con ListView y creo que es un gran descuido de Xamarin con Forms. Necesitamos mostrar dinámicamente los objetos manejados por los datos en más que solo una lista que está disminuyendo ... ¡vamos ya!

Sin embargo, en el proyecto de Xamarin Labs hay GridView que puedes usar. Todavía es un poco difícil y la gente está trabajando en algunos errores ahora con la selección de los elementos.

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

Alguien parece tener una solución alternativa para ese problema:

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


Como se señaló anteriormente, no existe una forma estándar de hacerlo, sin embargo, hay una forma de evitarlo utilizando un enfoque estándar de ListView y @MillieSmiths.

La solución necesita varias capas de diseños anidados. Comenzando con ListViewwe rotará esos 270 grados, sin embargo, eso también rota el contenido de nuestro artículo, por lo que debemos girarlo 90 grados hacia atrás.

Al rotar el ListView se crea una gran cantidad de espacios en blanco, al envolver el ListView en un diseño absoluto podemos resolverlo (necesitamos una vista de contenido adicional para solucionar algunos problemas de recorte).

Finalmente, en el código subyacente debemos renderizar el trazado de recorte

He aquí la solución completa:

<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>

Para el código detrás, solo necesitamos verificar si hemos configurado las cosas antes, si es que las tenemos, déjenlo ir. Básicamente estamos descubriendo cuál es el ancho de la página ( NameGrid es simplemente un contenedor de ancho completo en otro lugar), luego moviendo el contenedor directo de ListView a la mitad del espacio en blanco y recortándolo por la otra mitad en la parte inferior.

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; // */ } }

ADVERTENCIA NO USE <FRAMES> para que la disposición se mueva y gire. Se bloqueará en Windows Phone.

PD. Estoy seguro de que esto podría estar envuelto en un agradable UserControl para que todos lo usen.


Como todos han dicho, No, no hay uno disponible de fábrica en Xamarin.Forms .

Sin embargo, no impide que alguien escriba su propio procesador personalizado para lograr este tipo de control.

Como ha mencionado Stephane Delcroix , puede crear un ScrollView y luego un StackLayout como un niño para crear el mismo efecto.

Luego deberá implementar:

*) propiedad enlazable para aceptar la propiedad ( IEnumerable ) ItemsSource que necesita crear.

*) propiedad enlazable para aceptar la propiedad ( ItemTemplate ) ItemTemplate que necesita crear.

*) código de vinculación para instanciar instancias de ItemTemplate tomando el elemento de fuente de datos específico y convirtiéndolo en StackLayout . Tienes que considerar elementos eliminados, etc. también.

*) adjuntar controladores de eventos / gestos de toque para la selección de elementos.

*) implementando un estado seleccionado / desactivando otros elementos seleccionados.

... y así sucesivamente para obtener una implementación completa.

El problema con todo lo anterior es que está bien para listas de artículos relativamente pequeñas.

Sin embargo, si está buscando una larga lista de entradas, lo anterior sería un poco indeseable ya que está creando todas las Vistas por adelantado.

Incluso si retrasó la carga de estos, todavía tiene la huella de memoria de todas las Vistas a considerar.

Esto nos lleva a otra implementación posible que trata con Elementos virtualizados , que es una historia totalmente diferente a considerar.


Este paquete Nuget se ajustará perfectamente a su caso. He usado este antes y realmente me gusta:

https://github.com/SuavePirate/DynamicStackLayout

Para hacer las cosas aún mejor, descargue estos 3 paquetes de Nuget para tener una carga de imagen, almacenamiento en caché y transformación en sus fotos. Las fotos se formarán en un círculo, pero este nuget tiene otros tipos de transformaciones:

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)

Aquí hay una pieza de código para ayudarlo a comenzar:

<!--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>

Espero que ayude :)


Esto se ha resuelto con una clase personalizada llamada ItemsView (que no debe confundirse con ItemsView de Xamarin para plantillas de datos en un ListView) que implementa un patrón ScrollView / StackPanel mencionado anteriormente, cuyo ejemplo ya se ha solicitado. Por favor, vea el código: https://gist.github.com/fonix232/b88412a976f67315f915


Hasta donde yo sé, hay 3 formas de implementar esto:

  1. Rotación ( como lo mencionaron otros muchachos )
    • Ya no es necesario hacer ese ListView estándar
    • ItemTemplate está disponible
    • ¡Solución fea!
  2. Custom Render ( RecyclerView en Android y (creo) UICollectionView en iOS )
    • La celda personalizada está disponible (estoy seguro de que es Android, pero no estoy seguro acerca de iOS)
    • Necesita más trabajo y código
  3. Cuadrícula y vista de desplazamiento horizontal ( usando horizontal como valor para orientación prop en ScrollView )
    • Diseño personalizado está disponible
    • No hay CachingStrategy disponible en esta solución, por lo que para una gran lista esto puede causar un gran uso de RAM para su aplicación

He probado la solución mencionada de "rotación" y, además de ser una solución "fea", también presenta varias limitaciones :

  1. vista de lista WidthRequest debe ser igual a HeightRequest
  2. La altura de la fila listView ya no funciona correctamente porque se convierte en el ancho de la celda
  3. verticalalign se convierte en horizontalalign, etc., no muy fácil de mantener.

Una mejor opción es hacer su propio control personalizado o, como yo lo hice, usar un HorizontalListView existente : https://www.nuget.org/packages/HorizontalListView1.1/ Este es fácil de usar. Puede encontrar el código fuente y la documentación here

Implementación:

<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>



No, no hay forma de tener un ListView horizontal. Puede envolver un StackLayout horizontal en un ScrollView horizontal para lograr el mismo resultado visual, pero eso no es lo mismo, ya que no tendrá DataTemplating.


Sí, técnicamente puedes. Establezca la rotación en 270 (todos los elementos visuales tienen una propiedad de unión de rotación). Sin embargo, esto parece una solución subóptima ya que hay espacios en blanco en la parte superior e inferior y debe arrastrar la vista hacia la izquierda y hacia la derecha para ver todo completamente.

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

El código anterior es de la clase VisualElement. El siguiente código es una pequeña muestra mía.

∨∨∨ <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>