web-dev-qa-db-ja.com

水平リストビューXamarin.Forms

horizontal scrollのようなXamarin.FormsListViewを作成する方法はありますか

ListView Horizontal

これは私が垂直にやったことです

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

はい、できます。 Rotationを270に設定します(すべてのVisualElementにはRotation 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>
11
Millie Smith

他の皆が言ったように、いいえ-Xamarin.Formsにはすぐに使えるものはありません。

ただし、このタイプの制御を実現するために独自のカスタムレンダラーを作成することを誰も止めません。

Stephane Delcroixで述べたように、ScrollViewを作成し、次にStackLayoutを子として作成して同じ効果を作成できます。

その後、実装する必要があります:-

*)バインド可能なプロパティを受け入れて(IEnumerableItemsSource作成が必要なプロパティ.

*)バインド可能なプロパティDataTemplate)を受け入れますItemTemplate作成が必要なプロパティ.

*)bindingItemTemplateのインスタンスを作成するコード。特定のデータソース項目を取得し、これをStackLayoutにレンダリングします。削除されたアイテムなども考慮する必要があります。

*)アイテム選択のためのイベントハンドラー/タップジェスチャをアタッチします。

*)選択された状態の実装/他の選択されたアイテムの無効化。

...など、完全な実装を取得します。

上記のすべての問題は、比較的小さなアイテムリストには問題ないことです。

ただし、エントリの長いリストを探している場合は、上記のすべてのViewsを作成するため、上記は少し望ましくありません。

遅延ロードこれらの場合でも、考慮すべきすべてのViewsメモリフットプリントがあります。

次に、これはVirtualized Itemsを扱う別の可能な実装につながります。これは、考慮すべきまったく異なる話です。

10
Pete

上記で指摘したように、これを行う標準的な方法はありませんが、標準のListViewおよび@MillieSmithsアプローチを使用して回避する方法があります。

ソリューションには、ネストされたレイアウトの複数のレイヤーが必要です。 ListViewweから開始すると、その270度回転しますが、これによりアイテムのコンテンツも回転するため、その回転を90度戻す必要があります。

ListViewを回転させると、ListViewを絶対レイアウトでラップすることで非常に多くの空白が作成されます(いくつかのクリッピングの問題を修正するには、追加のcontentviewが必要です)。

最後に、コードビハインドでレイアウトのクリッピングをレンダリングする必要があります

完全なソリューションをご覧ください。

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

[〜#〜] warning [〜#〜]使用しない<FRAMES>移動および回転するレイアウト用。 Windows Phoneではクラッシュします。

追伸:これは、すべての人が使用できるようにすてきなUserControlにまとめられると確信しています。

10
Peter

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

他の人が言ったように、ListViewでは不可能であり、XamarinとFormsでは大きな見落としだと思います。リストだけでなく、データ駆動型オブジェクトを動的に表示する必要があります。

ただし、Xamarin Labsプロジェクトには、使用できるGridViewがあります。それはまだ少しラフであり、人々は現在アイテムを選択することでいくつかのバグを処理しています。

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

誰かがその問題の回避策を持っているようです:

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

7
Daniel Nelson

いいえ、水平ListViewを使用する方法はありません。水平方向のStackLayoutを水平方向のScrollViewにラップして同じ視覚的結果を得ることができますが、DataTemplatingがないため、まったく同じではありません。

6

私は試していませんが、これはチェックアウトする価値があるかもしれません。

https://github.com/Cheesebaron/Cheesebaron.Horizo​​ntalListView

3
Damien Sawyer

前述の「回転」ソリューションを試しましたが、「ugい」ソリューションであることに加えて、いくつかの制限があります

  1. リストビューWidthRequestはHeightRequestと同じである必要があります
  2. listViewの行の高さは、セル幅になるため、適切に機能しなくなりました
  3. verticalalignはhorizo​​ntalalignなどになりますが、保守性はあまりありません。

より良いオプションは、独自のカスタムコントロールを作成するか、既存のHorizo​​ntalListViewを使用することです: https://www.nuget .org/packages/Horizo​​ntalListView1.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>
2
Niels

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

私はそれが役立つことを願っています:)

Xamarin.Forms 4.0-preでは、 CollectionView を使用できます。これにより、このタイプのレイアウトを簡単に取得できます。

サンプル:

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

CollectionView が出るまで、Xamarin.Forms Horizo​​ntalListView を使用できます。

次のものがあります。

  • 最初または中間の要素でスナップ
  • パディングとアイテムの間隔
  • NotifyCollectionChangedActionの追加、削除、リセットアクションを処理します
  • リサイクルを見る
  • AndroidのRecyclerView
  • IOSのUICollectionView
  • 実際、この実装は、哲学と実装に関して、将来のXamarin CollectionViewを提供するものに非常に近いものです。
1
Roubachof

私の知る限り、これを実装するには3つの方法があります。

  1. ローテーション(他の人が言ったように
    • もう標準のListViewを行う必要はありません
    • ItemTemplateが利用可能です
    • Glyいソリューション!
  2. カスタムレンダリング(RecyclerView in Android and(I think)UICollectionView in iOS
    • カスタムセルが利用可能です(Androidについては確信していますが、iOSについては確信がありません)
    • より多くの作業とコードが必要
  3. グリッドおよび水平ScrollView(ScrollViewの方向支柱の値として水平を使用
    • カスタムレイアウトが利用可能
    • このソリューションではCachingStrategyが利用できないため、巨大なリストの場合、アプリの巨大なRAM
0
Mehdi Dehghani