wake-up-neo.com

Horizontale ListView Xamarin.Forms

Ist eine Möglichkeit, ListView mit horizontal scroll inXamarin.Formswie Bild zu erstellen 

ListView Horizontal

das ist was ich für vertikal gemacht habe 

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

Ja, das kannst du technisch. Legen Sie die Rotation auf 270 fest (alle VisualElements haben eine Rotation BindableProperty). Dies sieht jedoch nach einer suboptimalen Lösung aus, da oben und unten weiße Räume vorhanden sind und Sie die Ansicht nach links und rechts ziehen müssen, um alles vollständig zu sehen. 

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

Der obige Code stammt aus der VisualElement-Klasse. Der folgende Code ist ein kleines Beispiel von mir. 

                                              ∨∨∨                                                  
<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>
11
Millie Smith

Wie alle anderen gesagt haben: Nein - in Xamarin.Forms ist kein Standardsatz verfügbar.

Es hält jedoch niemanden davon ab, seinen eigenen benutzerdefinierten Renderer zu schreiben, um diese Art der Steuerung zu erreichen.

Wie in Stephane Delcroix erwähnt, können Sie als Kind ein ScrollView und dann ein StackLayout erstellen, um denselben Effekt zu erzeugen.

Sie müssen dann Folgendes implementieren: -

*) bindable-Eigenschaft, um die (IEnumerable) ItemsSource -Eigenschaft anzunehmen, die erstellt werden muss. 

*) bindable-Eigenschaft, um die (DataTemplate) ItemTemplate -Eigenschaft anzunehmen, die erstellt werden muss.

*) binding - Code, um Instanzen des ItemTemplate zu instanziieren, indem das bestimmte Datenquellenelement in das StackLayout gerendert wird. Sie müssen auch Elemente berücksichtigen, die entfernt wurden.

*) Fügen Sie Event-Handler/Tipp-Gesten für die Elementauswahl hinzu. 

*) Implementieren eines ausgewählten Status/Deaktivieren anderer ausgewählter Elemente.

... und so weiter, um eine vollständige Implementierung zu erhalten.

Das Problem bei all dem oben genannten ist, dass es für relativ kleine Artikellisten geeignet ist.

Wenn Sie jedoch nach einer langen Liste von Einträgen suchen, wäre das oben etwas unerwünscht, da Sie alle Views upfront erstellen. 

Auch wenn Sie verzögertes Laden von von diesen haben, müssen Sie immer noch den memory footprint aller Views beachten.

Dies führt dann zu einer anderen möglichen Implementierung, die sich mit Virtualized Items befasst, was eine völlig andere Geschichte ist.

10
Pete

Wie oben erwähnt, gibt es keine Standardmethode, jedoch gibt es eine Möglichkeit, die Standardvariablen ListView und @MillieSmiths zu verwenden.

Die Lösung benötigt mehrere Ebenen verschachtelter Layouts. Wenn wir mit ListView beginnen, drehen wir diese um 270 Grad, was jedoch auch den Artikelinhalt dreht. Wir müssen diesen also um 90 Grad zurückdrehen.

Durch Drehen der ListView wird eine Menge Whitespace erzeugt. Durch das Einbetten der ListView in ein absolutes Layout können wir das lösen (wir benötigen eine zusätzliche Inhaltsansicht, um einige Beschneidungsprobleme zu beheben).

Schließlich müssen wir im Codebehind den Layoutausschnitt rendern

Seht die vollständige Lösung:

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

Für den Code dahinter müssen wir nur prüfen, ob wir die Dinge vorher eingerichtet haben. Grundsätzlich erfahren wir, wie breit die Seite ist (NameGrid ist nur ein anderer Container mit voller Breite), dann verschieben Sie den direkten ListView-Container um die Hälfte des Whitespaces und schneiden ihn mit der anderen Hälfte unten ab.

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

WARNING VERWENDEN SIE NICHT <FRAMES> für das Verschieben und Drehen des Layouts. Es wird unter Windows Phone abstürzen.

P.S Ich bin mir sicher, dass dies in einem Nice UserControl für jedermann eingepackt werden kann.

10
Peter

Ab Xamarin Forms 2.3 macht CarouselView genau das und noch viel mehr. Lesen Sie mehr hier .

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

Wie die anderen schon sagten, mit ListView nicht möglich und ich denke, es ist ein großes Versehen von Xamarin mit Forms. Wir müssen datengesteuerte Objekte in mehr als nur einer Liste anzeigen lassen, die sich als unvollständig herausstellt.

Im Xamarin Labs-Projekt gibt es jedoch GridView, das Sie verwenden können. Es ist immer noch ein bisschen rau und die Leute arbeiten jetzt mit einigen Fehlern beim Auswählen der Elemente.

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

Jemand scheint dieses Problem zu umgehen:

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

7
Daniel Nelson

Nein, es gibt keine Möglichkeit, ein horizontales ListView zu haben. Sie können ein horizontales StackLayout in eine horizontale Bildlaufansicht umschließen, um das gleiche visuelle Ergebnis zu erzielen. Dies ist jedoch nicht ganz das gleiche, da Sie keine DataTemplating-Funktion haben.

6

Ich habe es nicht ausprobiert, aber es lohnt sich vielleicht.

https://github.com/Cheesebaron/Cheesebaron.HorizontalListView

3
Damien Sawyer

Ich habe die erwähnte "rotierende" Lösung ausprobiert und abgesehen davon, dass es sich um eine "hässliche" Lösung handelt, gibt es auch einige Einschränkungen :

  1. listenansicht WidthRequest muss mit HeightRequest identisch sein
  2. die Zeilenhöhe von listView funktioniert nicht mehr ordnungsgemäß, da sie zur Zellenbreite wird
  3. verticalalign wird zu Horizontalalign usw., nicht sehr wartbar.

Eine bessere Option ist, ein eigenes benutzerdefiniertes Steuerelement zu erstellen oder, wie ich es getan habe, eine vorhandene HorizontalListView zu verwenden : https://www.nuget .org/packages/HorizontalListView1.1 / Diese ist einfach zu bedienen. Sie finden den Quellcode und die Dokumentation hier

Implementierung:

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

Dieses Nuget-Paket passt perfekt zu Ihrem Fall. Ich habe dieses schon einmal benutzt und ich mag es wirklich:

https://github.com/SuavePirate/DynamicStackLayout

Laden Sie diese 3 Nuget-Pakete herunter, um Bilder zu laden, zu cachen und umzuwandeln. Die Fotos werden in einem Kreis geformt, aber dieses Nuget hat andere Arten von Transformationen:

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)

Hier ist ein Code, der Ihnen beim Start helfen soll: 

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

Ich hoffe, es hilft :)

Soweit ich weiß, gibt es drei Möglichkeiten, dies zu implementieren:

  1. Rotation ( wie von anderen Jungs erwähnt )
    • Diese Standard-ListView-Funktion muss nicht mehr ausgeführt werden
    • ItemTemplate ist verfügbar
    • Hässliche Lösung!
  2. Benutzerdefiniertes Rendern ( RecyclerView in Android und (ich denke) UICollectionView in iOS )
    • Benutzerdefinierte Zelle ist verfügbar (Ich bin mir sicher, was Android betrifft, aber nicht sicher über iOS)
    • Benötigt mehr Arbeit und Code
  3. Raster und horizontale ScrollView ( mit horizontalem Wert als Orientierungshilfe in ScrollView )
    • Benutzerdefiniertes Layout ist verfügbar
    • In dieser Lösung ist kein CachingStrategy verfügbar. Bei einer großen Liste kann dies zu einer erheblichen RAM - Verwendung Ihrer App führen
0
Mehdi Dehghani

In Xamarin.Forms 4.0-pre können Sie die CollectionView verwenden, die das Erstellen dieser Art von Layout vereinfacht.

Probe:

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

Bis das CollectionView out ist, können Sie meine Xamarin.Forms HorizontalListView verwenden.

Es hat:

  • Erstes oder mittleres Element einrasten
  • Polsterung und Abstand der Artikel
  • Behandelt NotifyCollectionChangedAction Aktionen hinzufügen, entfernen und zurücksetzen
  • Recycling anzeigen
  • RecyclerView auf Android
  • UICollectionView unter iOS
  • Diese Implementierung ist in der Tat sehr nah an der Philosophie und der Implementierung an die zukünftige Xamarin CollectionView.
0
Roubachof