ListView の外観

Download Sampleサンプルのダウンロード

Xamarin.FormsListView を使用すると、リスト内の各行の ViewCell インスタンスに加えて、リストの表示をカスタマイズできます。

グループ化

連続してスクロール リスト内に表示されると、大量のデータ セットは扱いにくくなる場合があります。 グループ化を有効にすると、コンテンツをより適切に整理し、データの移動をより容易にするプラットフォーム固有のコントロールをアクティブにして、このような場合のユーザー エクスペリエンスを向上させることができます。

ListView のグループ化がアクティブになると、グループごとにヘッダー行が追加されます。

グループ化を有効にするには:

  • リストのリスト (グループのリスト、各グループが要素のリスト) を作成します。
  • ListViewItemsSource にそのリストを設定します。
  • IsGroupingEnabled を true に設定します。
  • GroupDisplayBinding を設定して、グループのプロパティ (そのグループのタイトルとして使用されているもの) とバインドします。
  • [省略可能] GroupShortNameBinding を設定して、グループのプロパティ (そのグループの短い名前として使用されているもの) にバインドします。 この短い名前は、ジャンプ リスト (iOS 上の右側の列) に使用されます。

まず、グループのクラスを作成します。

public class PageTypeGroup : List<PageModel>
    {
        public string Title { get; set; }
        public string ShortName { get; set; } //will be used for jump lists
        public string Subtitle { get; set; }
        private PageTypeGroup(string title, string shortName)
        {
            Title = title;
            ShortName = shortName;
        }

        public static IList<PageTypeGroup> All { private set; get; }
    }

上記のコードで、All はバインディング ソースとして ListView に指定されるリストです。 TitleShortName はグループ見出しに使用されるプロパティです。

この段階で All は空のリストです。 プログラムの開始時にこのリストが設定されるように静的コンストラクターを追加します。

static PageTypeGroup()
{
    List<PageTypeGroup> Groups = new List<PageTypeGroup> {
            new PageTypeGroup ("Alpha", "A"){
                new PageModel("Amelia", "Cedar", new switchCellPage(),""),
                new PageModel("Alfie", "Spruce", new switchCellPage(), "grapefruit.jpg"),
                new PageModel("Ava", "Pine", new switchCellPage(), "grapefruit.jpg"),
                new PageModel("Archie", "Maple", new switchCellPage(), "grapefruit.jpg")
            },
            new PageTypeGroup ("Bravo", "B"){
                new PageModel("Brooke", "Lumia", new switchCellPage(),""),
                new PageModel("Bobby", "Xperia", new switchCellPage(), "grapefruit.jpg"),
                new PageModel("Bella", "Desire", new switchCellPage(), "grapefruit.jpg"),
                new PageModel("Ben", "Chocolate", new switchCellPage(), "grapefruit.jpg")
            }
        };
        All = Groups; //set the publicly accessible list
}

上記のコードでは、PageTypeGroup 型のインスタンスである Groups の要素に対して Add を呼び出すこともできます。 このメソッドを呼び出せるのは、PageTypeGroupList<PageModel> を継承しているためです。

グループ化されたリストを表示するための XAML を次に示します。

<?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="DemoListView.GroupingViewPage"
    <ContentPage.Content>
        <ListView  x:Name="GroupedView"
                   GroupDisplayBinding="{Binding Title}"
                   GroupShortNameBinding="{Binding ShortName}"
                   IsGroupingEnabled="true">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextCell Text="{Binding Title}"
                              Detail="{Binding Subtitle}" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ContentPage.Content>
</ContentPage>

この XAML は次のアクションを実行します。

  • GroupShortNameBinding にグループ クラスの中で定義した ShortName プロパティを設定します
  • GroupDisplayBinding にグループ クラスの中で定義した Title プロパティを設定します
  • IsGroupingEnabled に true を設定します
  • ListViewItemsSource をグループ化されたリストに変更します

次のスクリーンショットは、結果の UI を示しています。

ListView Grouping Example

グループ化のカスタマイズ

リスト内でグループ化が有効な場合は、グループ ヘッダーをカスタマイズすることもできます。

ListView に行の表示方法を定義する ItemTemplate があるのと同様に、ListView には GroupHeaderTemplate があります。

XAML 内でグループ ヘッダーをカスタマイズする例を次に示します。

<?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="DemoListView.GroupingViewPage">
    <ContentPage.Content>
        <ListView x:Name="GroupedView"
                  GroupDisplayBinding="{Binding Title}"
                  GroupShortNameBinding="{Binding ShortName}"
                  IsGroupingEnabled="true">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextCell Text="{Binding Title}"
                              Detail="{Binding Subtitle}"
                              TextColor="#f35e20"
                              DetailColor="#503026" />
                </DataTemplate>
            </ListView.ItemTemplate>
            <!-- Group Header Customization-->
            <ListView.GroupHeaderTemplate>
                <DataTemplate>
                    <TextCell Text="{Binding Title}"
                              Detail="{Binding ShortName}"
                              TextColor="#f35e20"
                              DetailColor="#503026" />
                </DataTemplate>
            </ListView.GroupHeaderTemplate>
            <!-- End Group Header Customization -->
        </ListView>
    </ContentPage.Content>
</ContentPage>

ヘッダーとフッター

ListView では、リストの要素と共にスクロールするヘッダーとフッターを表示できます。 ヘッダーとフッターは、テキストの文字列、またはより複雑なレイアウトにすることができます。 この動作は、「グループ化」のセクションとは別のものです。

HeaderFooterstring 値を設定する、またはより複雑なレイアウトを設定することができます。 データ バインディングをサポートするヘッダーとフッターの、より複雑なレイアウトを作成できる HeaderTemplateFooterTemplate プロパティもあります。

基本的なヘッダー/フッターを作成するには、ヘッダーまたはフッターのプロパティに、表示するテキストを設定するだけです。 コード内で以下のように指定します。

ListView HeaderList = new ListView()
{
    Header = "Header",
    Footer = "Footer"
};

XAML の場合:

<ListView x:Name="HeaderList" 
          Header="Header"
          Footer="Footer">
    ...
</ListView>

ListView with Header and Footer

カスタマイズしたヘッダーとフッターを作成するには、ヘッダーおよびフッター ビューを定義します。

<ListView.Header>
    <StackLayout Orientation="Horizontal">
        <Label Text="Header"
               TextColor="Olive"
               BackgroundColor="Red" />
    </StackLayout>
</ListView.Header>
<ListView.Footer>
    <StackLayout Orientation="Horizontal">
        <Label Text="Footer"
               TextColor="Gray"
               BackgroundColor="Blue" />
    </StackLayout>
</ListView.Footer>

ListView with Customized Header and Footer

スクロールバーの表示

ListView クラスには HorizontalScrollBarVisibilityVerticalScrollBarVisibility プロパティがあります。これらは、水平または垂直スクロール バーが表示されるタイミングを表す ScrollBarVisibility 値を取得または設定します。 両方のプロパティに次の値を設定できます。

  • Default は、プラットフォームの既定のスクロール バーの動作を示し、VerticalScrollBarVisibility および HorizontalScrollBarVisibility プロパティの既定値です。
  • Always は、コンテンツがビューに収まる場合でも、スクロール バーが表示されることを示します。
  • Never は、コンテンツがビューに収まらない場合でもスクロール バーが表示されないことを示します。

行区切り

iOS と Android 上では、ListView 要素間に既定で区切り線が表示されます。 iOS と Android 上で区切り線を非表示にする場合は、ListView 上で SeparatorVisibility プロパティを設定します。 SeparatorVisibility のオプションは次のとおりです。

  • Default - iOS と Android 上で区切り線を表示します。
  • None - すべてのプラットフォーム上で区切りを非表示にします。

既定の可視性:

C#:

SeparatorDemoListView.SeparatorVisibility = SeparatorVisibility.Default;

XAML:

<ListView x:Name="SeparatorDemoListView" SeparatorVisibility="Default" />

ListView with Default Row Separators

None:

C#:

SeparatorDemoListView.SeparatorVisibility = SeparatorVisibility.None;

XAML:

<ListView x:Name="SeparatorDemoListView" SeparatorVisibility="None" />

ListView without Row Separators

SeparatorColor プロパティを使用して区切り線の色を設定することもできます。

C#:

SeparatorDemoListView.SeparatorColor = Color.Green;

XAML:

<ListView x:Name="SeparatorDemoListView" SeparatorColor="Green" />

ListView with Green Row Separators

Note

Android 上で ListView の読み込み後にこれらのプロパティのいずれかを設定すると、パフォーマンスの大幅な低下を招きます。

行の高さ

既定では、ListView 内のすべての行の高さは同じです。 ListView には、その動作を変更するために使用できる 2 つのプロパティがあります。

  • HasUnevenRowstrue/false 値、true を設定した場合、行の高さは可変になります。 既定値は false です。
  • RowHeightHasUnevenRowsfalse の場合に、各行の高さを設定します。

ListView 上の RowHeight プロパティを設定すると、すべての行の高さを設定できます。

カスタム固定行の高さ

C#:

RowHeightDemoListView.RowHeight = 100;

XAML:

<ListView x:Name="RowHeightDemoListView" RowHeight="100" />

ListView with Fixed Row Height

不均一な行

個々の行に異なる高さを設定する場合は、HasUnevenRows プロパティに true を設定できます。 HasUnevenRowstrue を設定すると、Xamarin.Forms によって高さが自動的に計算されるため、手動で行の高さを設定する必要はありません。

C#:

RowHeightDemoListView.HasUnevenRows = true;

XAML:

<ListView x:Name="RowHeightDemoListView" HasUnevenRows="true" />

ListView with Uneven Rows

実行時に行のサイズを変更する

HasUnevenRowsプロパティに true を設定した場合、実行時に個々の ListView 行をプログラムでサイズ変更できます。 次のコード例の中で示したように、Cell.ForceUpdateSize メソッドはセルのサイズを (現在表示されていない場合でも) 更新します。

void OnImageTapped (object sender, EventArgs args)
{
    var image = sender as Image;
    var viewCell = image.Parent.Parent as ViewCell;

    if (image.HeightRequest < 250) {
        image.HeightRequest = image.Height + 100;
        viewCell.ForceUpdateSize ();
    }
}

OnImageTapped イベント ハンドラーは、セル内のタップされている Image に応答して実行され、セル内に表示される Image のサイズが大きくなり、見やすくなります。

ListView with Runtime Row Resizing

警告

ランタイムでの行サイズ変更を過度に使用すると、パフォーマンスの低下が発生する場合があります。