Bagikan melalui


ListView

Telusuri sampel. Telusuri sampel

UI Aplikasi Multi-platform .NET (.NET MAUI) ListView menampilkan daftar vertikal yang dapat digulir dari item data yang dapat dipilih. Saat ListView mengelola tampilan daftar, tampilan setiap item dalam daftar ditentukan oleh DataTemplate yang menggunakan Cell untuk menampilkan item. .NET MAUI menyertakan jenis sel untuk menampilkan kombinasi teks dan gambar, dan Anda juga dapat menentukan sel kustom yang menampilkan konten apa pun yang Anda inginkan. ListView juga mencakup dukungan untuk menampilkan header dan footer, data yang dikelompokkan, pull-to-refresh, dan item menu konteks.

Kelas ListView berasal dari ItemsView<Cell> kelas , dari mana ia mewarisi properti berikut:

  • ItemsSource, dari jenis IEnumerable, menentukan kumpulan item yang akan ditampilkan, dan memiliki nilai nulldefault .
  • ItemTemplate, dari jenis DataTemplate, menentukan templat yang akan diterapkan ke setiap item dalam kumpulan item yang akan ditampilkan.

ListView menentukan properti berikut:

  • Footer, dari jenis object, menentukan string atau tampilan yang akan ditampilkan di akhir daftar.
  • FooterTemplate, dari jenis DataTemplate, menentukan DataTemplate untuk digunakan untuk memformat Footer.
  • GroupHeaderTemplate, dari jenis DataTemplate, mendefinisikan yang DataTemplate digunakan untuk menentukan tampilan header dari setiap grup. Properti ini saling eksklusif dengan GroupDisplayBinding properti. Oleh karena itu, pengaturan properti ini akan diatur GroupDisplayBinding ke null.
  • HasUnevenRows, dari jenis bool, menunjukkan apakah item dalam daftar dapat memiliki baris dengan tinggi yang berbeda. Nilai default properti ini adalah false.
  • Header, dari jenis object, menentukan string atau tampilan yang akan ditampilkan di awal daftar.
  • HeaderTemplate, dari jenis DataTemplate, menentukan DataTemplate untuk digunakan untuk memformat Header.
  • HorizontalScrollBarVisibility, dari jenis ScrollBarVisibility, menunjukkan kapan bilah gulir horizontal akan terlihat.
  • IsGroupedEnabled, dari jenis bool, menunjukkan apakah data yang mendasar harus ditampilkan dalam grup. Nilai default properti ini adalah false.
  • IsPullToRefreshEnabled, dari jenis bool, menunjukkan apakah pengguna dapat menggesek ke bawah untuk menyebabkan ListView merefresh datanya. Nilai default properti ini adalah false.
  • IsRefreshing, dari jenis bool, menunjukkan apakah ListView saat ini sedang di-refresh. Nilai default properti ini adalah false.
  • RefreshCommand, dari jenis ICommand, mewakili perintah yang akan dijalankan ketika refresh dipicu.
  • RefreshControlColor, dari jenis Color, menentukan warna visualisasi refresh yang ditampilkan saat refresh terjadi.
  • RowHeight, dari jenis int, menentukan tinggi setiap baris ketika HasUnevenRows adalah false.
  • SelectedItem, dari jenis object, mewakili item yang saat ini dipilih di ListView.
  • SelectionMode, dari jenis ListViewSelectionMode, menunjukkan apakah item dapat dipilih dalam ListView atau tidak. Nilai default properti ini adalah Single.
  • SeparatorColor, dari jenis Color, menentukan warna bilah yang memisahkan item dalam daftar.
  • SeparatorVisibility, dari jenis SeparatorVisibility, menentukan apakah pemisah terlihat di antara item.
  • VerticalScrollBarVisibility, dari jenis ScrollBarVisibility, menunjukkan kapan bilah gulir vertikal akan terlihat.

Semua properti ini didukung oleh BindableProperty objek, yang berarti bahwa properti tersebut dapat menjadi target pengikatan data, dan ditata.

Selain itu, ListView tentukan properti berikut yang tidak didukung oleh BindableProperty objek:

  • GroupDisplayBinding, dari jenis BindingBase, pengikatan yang digunakan untuk menampilkan header grup. Properti ini saling eksklusif dengan GroupHeaderTemplate properti. Oleh karena itu, pengaturan properti ini akan diatur GroupHeaderTemplate ke null.
  • GroupShortNameBinding, dari jenis BindingBase, pengikatan untuk nama yang akan ditampilkan dalam daftar lompat yang dikelompokkan.
  • CachingStrategy, dari jenis ListViewCachingStrategy, mendefinisikan strategi penggunaan kembali sel dari ListView. Ini adalah properti baca-saja.

ListView mendefinisikan peristiwa berikut:

  • ItemAppearing, yang dinaikkan ketika representasi visual item sedang ditambahkan ke tata letak ListViewvisual . Objek ItemVisibilityEventArgs yang menyertai peristiwa ini mendefinisikan Item dan Index properti.
  • ItemDisappearing, yang dinaikkan ketika representasi visual item sedang dihapus dari tata letak ListViewvisual . Objek ItemVisibilityEventArgs yang menyertai peristiwa ini mendefinisikan Item dan Index properti.
  • ItemSelected, yang dimunculkan ketika item baru dalam daftar dipilih. Objek SelectedItemChangedEventArgs yang menyertai peristiwa ini mendefinisikan SelectedItem dan SelectedItemIndex properti.
  • ItemTapped, yang dimunculkan saat item dalam diketuk ListView . Objek ItemTappedEventArgs yang menyertai peristiwa ini mendefinisikan Groupproperti , , Itemdan ItemIndex .
  • Refreshing, yang dinaikkan ketika operasi tarik ke refresh dipicu pada ListView.
  • Scrolled, . Objek ScrolledEventArgs yang menyertai peristiwa ini mendefinisikan ScrollX dan ScrollY properti.
  • ScrollToRequested . Objek ScrollToRequestedEventArgs yang menyertai peristiwa ini mendefinisikan Elementproperti , , ModePosition, ScrollX, ScrollY, dan ShouldAnimate .

Mengisi ListView dengan data

ListView diisi dengan data dengan mengatur propertinya ItemsSource ke koleksi apa pun yang mengimplementasikan IEnumerable.

Penting

ListView Jika diperlukan untuk menyegarkan saat item ditambahkan, dihapus, atau diubah dalam koleksi yang mendasar, koleksi yang mendasar harus berupa IEnumerable koleksi yang mengirim pemberitahuan perubahan properti, seperti ObservableCollection.

ListView dapat diisi dengan data dengan menggunakan pengikatan data untuk mengikat propertinya ItemsSource ke IEnumerable koleksi. Di XAML, ini dicapai dengan Binding ekstensi markup:

<ListView ItemsSource="{Binding Monkeys}" />

Kode C# yang setara adalah:

ListView listView = new ListView();
listView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

Dalam contoh ini, ItemsSource data properti mengikat ke Monkeys properti viewmodel yang terhubung.

Catatan

Pengikatan yang dikompilasi dapat diaktifkan untuk meningkatkan performa pengikatan data dalam aplikasi .NET MAUI. Untuk informasi selengkapnya, lihat Pengikatan yang dikompilasi.

Untuk informasi selengkapnya tentang pengikatan data, lihat Pengikatan data.

Tentukan tampilan item

Tampilan setiap item dalam ListView dapat ditentukan dengan mengatur ItemTemplate properti ke DataTemplate:

<ListView ItemsSource="{Binding Monkeys}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Grid Padding="10">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Image Grid.RowSpan="2"
                           Source="{Binding ImageUrl}"
                           Aspect="AspectFill"
                           HeightRequest="60"
                           WidthRequest="60" />
                    <Label Grid.Column="1"
                           Text="{Binding Name}"
                           FontAttributes="Bold" />
                    <Label Grid.Row="1"
                           Grid.Column="1"
                           Text="{Binding Location}"
                           FontAttributes="Italic"
                           VerticalOptions="End" />
                </Grid>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Elemen yang ditentukan dalam DataTemplate menentukan tampilan setiap item dalam daftar, dan turunan dari DataTemplate harus berupa Cell objek. Dalam contoh, tata letak dalam DataTemplate dikelola oleh Grid. Grid berisi Image objek, dan dua Label objek, yang semuanya mengikat properti Monkey kelas:

public class Monkey
{
    public string Name { get; set; }
    public string Location { get; set; }
    public string Details { get; set; }
    public string ImageUrl { get; set; }
}

Cuplikan layar berikut menunjukkan hasil templat setiap item dalam daftar:

Cuplikan layar ListView tempat setiap item di-template.

Untuk informasi selengkapnya tentang templat data, lihat Templat data.

Sel

Tampilan setiap item dalam ListView ditentukan oleh DataTemplate, dan DataTemplate harus mereferensikan Cell kelas untuk menampilkan item. Setiap sel mewakili item data di ListView. .NET MAUI menyertakan sel bawaan berikut:

  • TextCell, yang menampilkan teks primer dan sekunder pada baris terpisah.
  • ImageCell, yang menampilkan gambar dengan teks primer dan sekunder pada baris terpisah.
  • SwitchCell, yang menampilkan teks dan sakelar yang dapat diaktifkan atau dinonaktifkan.
  • EntryCell, yang menampilkan label dan teks yang dapat diedit.
  • ViewCell, yang merupakan sel kustom yang penampilannya didefinisikan oleh View. Tipe sel ini harus digunakan ketika Anda ingin sepenuhnya menentukan tampilan setiap item dalam ListView.

Biasanya, SwitchCell dan EntryCell hanya akan digunakan dalam TableView dan tidak akan digunakan dalam ListView. Untuk informasi selengkapnya tentang SwitchCell dan EntryCell, lihat TableView.

Sel teks

Menampilkan TextCell teks primer dan sekunder pada baris terpisah. TextCell menentukan properti berikut:

  • Text, dari jenis string, menentukan teks utama yang akan ditampilkan.
  • TextColor, dari jenis Color, mewakili warna teks utama.
  • Detail, dari jenis string, menentukan teks sekunder yang akan ditampilkan.
  • DetailColor, dari jenis Color, menunjukkan warna teks sekunder.
  • Command, dari jenis ICommand, menentukan perintah yang dijalankan saat sel diketuk.
  • CommandParameter, dari jenis object, mewakili parameter yang diteruskan ke perintah .

Properti ini didukung oleh BindableProperty objek, yang berarti bahwa properti ini dapat menjadi target pengikatan data, dan ditata.

Contoh berikut menunjukkan penggunaan TextCell untuk menentukan tampilan item dalam :ListView

<ListView ItemsSource="{Binding Food}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextCell Text="{Binding Name}"
                      Detail="{Binding Description}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Cuplikan layar berikut menunjukkan tampilan sel yang dihasilkan:

Cuplikan layar ListView di mana setiap item adalah TextCell.

Sel gambar

Menampilkan ImageCell gambar dengan teks primer dan sekunder pada baris terpisah. ImageCell mewarisi properti dari TextCell, dan menentukan ImageSource properti, jenis ImageSource, yang menentukan gambar yang akan ditampilkan dalam sel. Properti ini didukung oleh BindableProperty objek, yang berarti dapat menjadi target pengikatan data, dan ditata.

Contoh berikut menunjukkan penggunaan ImageCell untuk menentukan tampilan item dalam :ListView

<ListView ItemsSource="{Binding Food}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ImageCell ImageSource="{Binding Image}"
                       Text="{Binding Name}"
                       Detail="{Binding Description}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Cuplikan layar berikut menunjukkan tampilan sel yang dihasilkan:

Cuplikan layar ListView di mana setiap item adalah ImageCell.

Tampilkan sel

adalah ViewCell sel kustom yang penampilannya didefinisikan oleh View. ViewCellView menentukan properti, jenis View, yang menentukan tampilan yang mewakili konten sel. Properti ini didukung oleh BindableProperty objek, yang berarti dapat menjadi target pengikatan data, dan ditata.

Catatan

Properti View adalah properti konten kelas ViewCell , dan oleh karena itu tidak perlu diatur secara eksplisit dari XAML.

Contoh berikut menunjukkan penggunaan ViewCell untuk menentukan tampilan item dalam :ListView

<ListView ItemsSource="{Binding Monkeys}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Grid Padding="10">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Image Grid.RowSpan="2"
                           Source="{Binding ImageUrl}"
                           Aspect="AspectFill"
                           HeightRequest="60"
                           WidthRequest="60" />
                    <Label Grid.Column="1"
                           Text="{Binding Name}"
                           FontAttributes="Bold" />
                    <Label Grid.Row="1"
                           Grid.Column="1"
                           Text="{Binding Location}"
                           FontAttributes="Italic"
                           VerticalOptions="End" />
                </Grid>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

ViewCellDi dalam tata letak , dapat dikelola oleh tata letak .NET MAUI apa pun. Dalam contoh ini, tata letak dikelola oleh Grid. Grid berisi Image objek, dan dua Label objek, yang semuanya mengikat properti Monkey kelas.

Cuplikan layar berikut menunjukkan hasil templat setiap item dalam daftar:

Cuplikan layar ListView tempat setiap item di-template dengan ViewCell.

Pilih tampilan item saat runtime

Tampilan setiap item dalam ListView dapat dipilih pada runtime, berdasarkan nilai item, dengan mengatur ItemTemplate properti ke DataTemplateSelector objek:

<ContentPage ...
             xmlns:templates="clr-namespace:ListViewDemos.Templates">
    <ContentPage.Resources>
        <DataTemplate x:Key="AmericanMonkeyTemplate">
            <ViewCell>
                ...
            </ViewCell>
        </DataTemplate>

        <DataTemplate x:Key="OtherMonkeyTemplate">
            <ViewCell>
                ...
            </ViewCell>
        </DataTemplate>

        <templates:MonkeyDataTemplateSelector x:Key="MonkeySelector"
                                             AmericanMonkey="{StaticResource AmericanMonkeyTemplate}"
                                             OtherMonkey="{StaticResource OtherMonkeyTemplate}" />
    </ContentPage.Resources>

    <StackLayout Margin="20">
        <ListView ItemsSource="{Binding Monkeys}"
                  ItemTemplate="{StaticResource MonkeySelector}" />
    </StackLayout>
</ContentPage>

Properti ItemTemplate diatur ke MonkeyDataTemplateSelector objek. Contoh berikut menunjukkan MonkeyDataTemplateSelector kelas:

public class MonkeyDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate AmericanMonkey { get; set; }
    public DataTemplate OtherMonkey { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        return ((Monkey)item).Location.Contains("America") ? AmericanMonkey : OtherMonkey;
    }
}

Kelas MonkeyDataTemplateSelector menentukan AmericanMonkey dan OtherMonkey DataTemplate properti yang diatur ke templat data yang berbeda. Penimpaan OnSelectTemplate AmericanMonkey mengembalikan templat, yang menampilkan nama monyet dan lokasi teal, ketika nama monyet berisi "Amerika". Ketika nama monyet tidak berisi "Amerika", OnSelectTemplate penimpaan OtherMonkey mengembalikan templat, yang menampilkan nama monyet dan lokasi dengan perak:

Cuplikan layar pilihan templat item runtime ListView.

Untuk informasi selengkapnya tentang pemilih templat data, lihat Membuat DataTemplateSelector.

Merespons pilihan item

Secara default, ListView pilihan diaktifkan. Namun, perilaku ini dapat diubah dengan mengatur SelectionMode properti . Enumerasi ListViewSelectionMode menentukan anggota berikut:

  • None – menunjukkan bahwa item tidak dapat dipilih.
  • Single – menunjukkan bahwa satu item dapat dipilih, dengan item yang dipilih disorot. Ini adalah nilai default.

ListViewItemSelected menentukan peristiwa yang dimunculkan saat SelectedItem properti berubah, baik karena pengguna memilih item dari daftar, atau saat aplikasi mengatur properti. Objek SelectedItemChangedEventArgs yang menyertai kejadian ini memiliki SelectedItem properti dan SelectedItemIndex .

SelectionMode Saat properti diatur ke Single, satu item dalam ListView dapat dipilih. Ketika item dipilih, SelectedItem properti akan diatur ke nilai item yang dipilih. Ketika properti ini berubah, ItemSelected peristiwa dinaikkan.

Contoh berikut menunjukkan ListView yang dapat merespons pilihan item tunggal:

<ListView ItemsSource="{Binding Monkeys}"
          ItemSelected="OnItemSelected">
    ...
</ListView>

Dalam contoh ini, OnItemSelected penanganan aktivitas dijalankan saat ItemSelected peristiwa diaktifkan, dengan penanganan aktivitas mengambil item yang dipilih:

void OnItemSelected(object sender, SelectedItemChangedEventArgs args)
{
    Monkey item = args.SelectedItem as Monkey;
}

Cuplikan layar berikut menunjukkan pilihan item tunggal dalam :ListView

Cuplikan layar ListView dengan pilihan.

Menghapus pilihan

Properti SelectedItem dapat dibersihkan dengan mengaturnya, atau objek yang diikatnya, ke null.

Nonaktifkan pilihan

ListView pilihan diaktifkan secara default. Namun, dapat dinonaktifkan dengan mengatur properti ke SelectionMode None:

<ListView ...
          SelectionMode="None" />

SelectionMode Ketika properti diatur ke None, item dalam ListView tidak dapat dipilih, SelectedItem properti akan tetap null, dan ItemSelected peristiwa tidak akan diaktifkan.

Data cache

ListView adalah tampilan yang kuat untuk menampilkan data, tetapi memiliki beberapa batasan. Performa pengguliran dapat menderita saat menggunakan sel kustom, terutama ketika berisi hierarki tampilan berlapis secara mendalam atau menggunakan tata letak tertentu yang memerlukan pengukuran kompleks. Untungnya, ada teknik yang dapat Anda gunakan untuk menghindari performa yang buruk.

Sering ListView digunakan untuk menampilkan lebih banyak data daripada cocok pada layar. Misalnya, aplikasi musik mungkin memiliki perpustakaan lagu dengan ribuan entri. Membuat item untuk setiap entri akan membuang memori berharga dan berkinerja buruk. Membuat dan menghancurkan baris terus-menerus akan mengharuskan aplikasi untuk membuat instans dan membersihkan objek terus-menerus, yang juga akan berkinerja buruk.

Untuk menghemat memori, setara asli ListView untuk setiap platform memiliki fitur bawaan untuk menggunakan kembali baris. Hanya sel yang terlihat di layar yang dimuat dalam memori dan konten dimuat ke dalam sel yang ada. Pola ini mencegah aplikasi membuat instans ribuan objek, menghemat waktu dan memori.

.NET MAUI mengizinkan ListView penggunaan kembali sel melalui ListViewCachingStrategy enumerasi, yang menentukan anggota berikut:

  • RetainElement, menentukan bahwa ListView akan menghasilkan sel untuk setiap item dalam daftar.
  • RecycleElement, menentukan bahwa ListView akan mencoba meminimalkan jejak memori dan kecepatan eksekusinya dengan mendaur ulang sel daftar.
  • RecycleElementAndDataTemplate, sebagai RecycleElement sementara juga memastikan bahwa ketika ListView menggunakan DataTemplateSelector, DataTemplate objek di-cache oleh jenis item dalam daftar.

Pertahankan elemen

Strategi RetainElement penembolokan menentukan bahwa ListView akan menghasilkan sel untuk setiap item dalam daftar, dan merupakan perilaku default ListView . Ini harus digunakan dalam keadaan berikut:

  • Setiap sel memiliki sejumlah besar pengikatan (20-30+).
  • Templat sel sering berubah.
  • Pengujian mengungkapkan bahwa RecycleElement strategi penembolokan menghasilkan kecepatan eksekusi yang berkurang.

Penting untuk mengenali konsekuensi dari RetainElement strategi penembolokan saat bekerja dengan sel kustom. Kode inisialisasi sel apa pun perlu dijalankan untuk setiap pembuatan sel, yang mungkin beberapa kali per detik. Dalam keadaan ini, teknik tata letak yang baik-baik saja di halaman, seperti menggunakan beberapa objek berlapis StackLayout , menjadi hambatan performa ketika mereka diatur dan dihancurkan secara real time saat pengguna menggulir.

Elemen daur ulang

Strategi RecycleElement penembolokan menentukan bahwa ListView akan mencoba meminimalkan jejak memori dan kecepatan eksekusinya dengan mendaur ulang sel daftar. Mode ini tidak selalu menawarkan peningkatan performa, dan pengujian harus dilakukan untuk menentukan peningkatan apa pun. Namun, ini adalah pilihan yang disukai, dan harus digunakan dalam keadaan berikut:

  • Setiap sel memiliki jumlah pengikatan kecil hingga sedang.
  • Setiap sel BindingContext menentukan semua data sel.
  • Setiap sel sebagian besar mirip, dengan templat sel tidak berubah.

Selama virtualisasi sel akan memperbarui konteks pengikatannya, dan jika aplikasi menggunakan mode ini, sel harus memastikan bahwa pembaruan konteks pengikatan ditangani dengan tepat. Semua data tentang sel harus berasal dari konteks pengikatan atau kesalahan konsistensi dapat terjadi. Masalah ini dapat dihindari dengan menggunakan pengikatan data untuk menampilkan data sel. Atau, data sel harus diatur dalam OnBindingContextChanged penimpaan, bukan di konstruktor sel kustom, seperti yang ditunjukkan dalam contoh berikut:

public class CustomCell : ViewCell
{
    Image image = null;

    public CustomCell()
    {
        image = new Image();
        View = image;
    }

    protected override void OnBindingContextChanged()
    {
        base.OnBindingContextChanged();

        var item = BindingContext as ImageItem;
        if (item != null)
        {
            image.Source = item.ImageUrl;
        }
    }
}

Mendaur ulang elemen dengan DataTemplateSelector

ListView Saat menggunakan DataTemplateSelector untuk memilih DataTemplate, RecycleElement strategi penembolokan tidak menyimpan objek cacheDataTemplate. Sebagai gantinya, DataTemplate dipilih untuk setiap item data dalam daftar.

Catatan

Strategi RecycleElement penembolokan mengharuskan ketika diminta DataTemplateSelector untuk memilih DataTemplate bahwa masing-masing DataTemplate harus mengembalikan jenis yang sama ViewCell . Misalnya, diberikan ListView dengan DataTemplateSelector yang dapat mengembalikan baik MyDataTemplateA (di mana MyDataTemplateA mengembalikan ViewCell jenis MyViewCellA), atau MyDataTemplateB (di mana MyDataTemplateB mengembalikan ViewCell jenis MyViewCellB), ketika MyDataTemplateA dikembalikan harus dikembalikan MyViewCellA atau pengecualian akan dilemparkan.

Elemen daur ulang dengan DataTemplates

Strategi RecycleElementAndDataTemplate penembolokan dibangun pada RecycleElement strategi penembolokan dengan juga memastikan bahwa ketika ListView menggunakan DataTemplateSelector untuk memilih DataTemplate, DataTemplate objek di-cache oleh jenis item dalam daftar. Oleh karena itu, DataTemplate objek dipilih sekali per jenis item, bukan sekali per instans item.

Catatan

Strategi RecycleElementAndDataTemplate penembolokan mengharuskan objek yang DataTemplate dikembalikan oleh DataTemplateSelector harus menggunakan DataTemplate konstruktor yang mengambil Type.

Mengatur strategi penembolokan

Strategi ListView penembolokan dapat didefinisikan oleh di XAML dengan mengatur CachingStrategy atribut:

<ListView CachingStrategy="RecycleElement">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
              ...
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Di C#, strategi penembolokan diatur melalui kelebihan beban konstruktor:

ListView listView = new ListView(ListViewCachingStrategy.RecycleElement);

Mengatur strategi penembolokan dalam ListView subkelas

CachingStrategy Mengatur atribut dari XAML pada subkelas ListView tidak akan menghasilkan perilaku yang diinginkan, karena tidak CachingStrategy ada properti pada ListView. Solusi untuk masalah ini adalah menentukan konstruktor pada subkelas ListView yang menerima ListViewCachingStrategy parameter dan meneruskannya ke kelas dasar:

public class CustomListView : ListView
{
    public CustomListView (ListViewCachingStrategy strategy) : base (strategy)
    {
    }
    ...
}

Kemudian nilai ListViewCachingStrategy enumerasi dapat ditentukan dari XAML dengan menggunakan x:Arguments atribut :

<local:CustomListView>
    <x:Arguments>
        <ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
    </x:Arguments>
</local:CustomListView>

Header dan footer

ListView dapat menyajikan header dan footer yang menggulir dengan item dalam daftar. Header dan footer dapat berupa string, tampilan, atau DataTemplate objek.

ListView menentukan properti berikut untuk menentukan header dan footer:

  • Header, dari jenis object, menentukan string, pengikatan, atau tampilan yang akan ditampilkan di awal daftar.
  • HeaderTemplate, dari jenis DataTemplate, menentukan DataTemplate untuk digunakan untuk memformat Header.
  • Footer, dari jenis object, menentukan string, pengikatan, atau tampilan yang akan ditampilkan di akhir daftar.
  • FooterTemplate, dari jenis DataTemplate, menentukan DataTemplate untuk digunakan untuk memformat Footer.

Properti ini didukung oleh BindableProperty objek, yang berarti bahwa properti dapat menjadi target pengikatan data.

Properti Header dan Footer dapat diatur ke string nilai, seperti yang ditunjukkan dalam contoh berikut:

<ListView ItemsSource="{Binding Monkeys}"
          Header="Monkeys"
          Footer="2022">
    ...
</ListView>

Cuplikan layar berikut menunjukkan header yang dihasilkan:

Cuplikan layar header string ListView.

Properti Header dan Footer masing-masing dapat diatur ke tampilan. Ini bisa berupa tampilan tunggal, atau tampilan yang berisi beberapa tampilan turunan. Contoh berikut menunjukkan Header properti dan Footer yang masing-masing diatur ke StackLayout objek yang berisi Label objek:

<ListView ItemsSource="{Binding Monkeys}">
    <ListView.Header>
        <StackLayout BackgroundColor="LightGray">
            <Label Margin="10,0,0,0"
                   Text="Monkeys"
                   FontSize="12"
                   FontAttributes="Bold" />
        </StackLayout>
    </ListView.Header>
    <ListView.Footer>
        <StackLayout BackgroundColor="LightGray">
            <Label Margin="10,0,0,0"
                   Text="Friends of Monkey"
                   FontSize="12"
                   FontAttributes="Bold" />
        </StackLayout>
    </ListView.Footer>
    ...
</ListView>

Cuplikan layar berikut menunjukkan header yang dihasilkan:

Cuplikan layar header dan footer CollectionView menggunakan tampilan.

Properti HeaderTemplate dan FooterTemplate dapat diatur ke DataTemplate objek yang digunakan untuk memformat header dan footer. Dalam skenario ini, Header properti dan Footer harus mengikat ke sumber saat ini agar templat diterapkan, seperti yang ditunjukkan dalam contoh berikut:

<ListView ItemsSource="{Binding Monkeys}"
          Header="{Binding .}"
          Footer="{Binding .}">
    <ListView.HeaderTemplate>
        <DataTemplate>
            <StackLayout BackgroundColor="LightGray">
                <Label Margin="10,0,0,0"
                       Text="Monkeys"
                       FontSize="12"
                       FontAttributes="Bold" />
            </StackLayout>
        </DataTemplate>
    </ListView.HeaderTemplate>
    <ListView.FooterTemplate>
        <DataTemplate>
            <StackLayout BackgroundColor="LightGray">
                <Label Margin="10,0,0,0"
                       Text="Friends of Monkey"
                       FontSize="12"
                       FontAttributes="Bold" />
            </StackLayout>
        </DataTemplate>
    </ListView.FooterTemplate>
    ...
</ListView>

Pemisah item kontrol

Secara default, pemisah ditampilkan di antara ListView item di iOS dan Android. Perilaku ini dapat diubah dengan mengatur SeparatorVisibility properti, dari jenis SeparatorVisibility, ke None:

<ListView ...
          SeparatorVisibility="None" />

Selain itu, ketika pemisah diaktifkan, warnanya dapat diatur dengan SeparatorColor properti :

<ListView ...
          SeparatorColor="Blue" />

Item ukuran

Secara default, semua item dalam ListView memiliki tinggi yang sama, yang berasal dari konten DataTemplate yang menentukan tampilan setiap item. Namun, perilaku ini dapat diubah dengan HasUnevenRows properti dan RowHeight . Secara default, HasUnevenRows propertinya adalah false.

Properti RowHeight dapat diatur ke int yang mewakili tinggi setiap item dalam ListView, asalkan HasUnevenRows .false Ketika HasUnevenRows diatur ke true, setiap item di ListView dapat memiliki tinggi yang berbeda. Tinggi setiap item akan berasal dari konten item DataTemplate, sehingga setiap item akan berukuran sesuai dengan kontennya.

Item individual ListView dapat diubah ukurannya secara terprogram pada runtime dengan mengubah properti elemen terkait tata letak dalam DataTemplate, asalkan HasUnevenRows properti adalah true. Contoh berikut mengubah tinggi Image objek saat diketuk:

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

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

Dalam contoh ini, penanganan OnImageTapped aktivitas dijalankan sebagai respons terhadap objek yang Image diketuk. Penanganan aktivitas memperbarui tinggi Image dan Cell.ForceUpdateSize metode memperbarui ukuran sel, bahkan ketika saat ini tidak terlihat.

Peringatan

Penggunaan ukuran item dinamis yang berlebihan dapat menyebabkan ListView performa terdegradasi.

Tata letak kanan-ke-kiri

ListView dapat mengatur tata letak kontennya dalam arah alur kanan-ke-kiri dengan mengatur propertinya FlowDirection ke RightToLeft. Namun, FlowDirection properti idealnya harus diatur pada halaman atau tata letak akar, yang menyebabkan semua elemen dalam halaman, atau tata letak akar, merespons arah alur:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ListViewDemos.RightToLeftListPage"
             Title="Right to left list"
             FlowDirection="RightToLeft">
    <StackLayout Margin="20">
        <ListView ItemsSource="{Binding Monkeys}">
            ...
        </ListView>
    </StackLayout>
</ContentPage>

Default FlowDirection untuk elemen dengan induk adalah MatchParent. Oleh karena itu, ListView mewarisi FlowDirection nilai properti dari StackLayout, yang pada gilirannya FlowDirection mewarisi nilai properti dari ContentPage.

Menampilkan data yang dikelompokkan

Himpunan data besar sering kali menjadi tidak berat ketika disajikan dalam daftar yang terus menggulir. Dalam skenario ini, mengatur data ke dalam grup dapat meningkatkan pengalaman pengguna dengan mempermudah menavigasi data.

Data harus dikelompokkan sebelum dapat ditampilkan. Ini dapat dicapai dengan membuat daftar grup, di mana setiap grup adalah daftar item. Daftar grup harus berupa IEnumerable<T> koleksi, di mana T mendefinisikan dua bagian data:

  • Nama grup.
  • Koleksi IEnumerable yang menentukan item milik grup.

Oleh karena itu, proses untuk mengelompokkan data adalah:

  • Buat jenis yang memodelkan satu item.
  • Buat jenis yang memodelkan satu grup item.
  • Buat IEnumerable<T> koleksi, di mana T adalah jenis yang memodelkan satu grup item. Koleksi ini adalah kumpulan grup, yang menyimpan data yang dikelompokkan.
  • Tambahkan data ke IEnumerable<T> koleksi.

Contoh

Saat mengelompokkan data, langkah pertama adalah membuat jenis yang memodelkan satu item. Contoh berikut menunjukkan Animal kelas:

public class Animal
{
    public string Name { get; set; }
    public string Location { get; set; }
    public string Details { get; set; }
    public string ImageUrl { get; set; }
}

Kelas memodelkan Animal satu item. Jenis yang memodelkan sekelompok item kemudian dapat dibuat. Contoh berikut menunjukkan AnimalGroup kelas:

public class AnimalGroup : List<Animal>
{
    public string Name { get; private set; }

    public AnimalGroup(string name, List<Animal> animals) : base(animals)
    {
        Name = name;
    }
}

Kelas AnimalGroup mewarisi dari List<T> kelas dan menambahkan Name properti yang mewakili nama grup.

Kumpulan IEnumerable<T> grup kemudian dapat dibuat:

public List<AnimalGroup> Animals { get; private set; } = new List<AnimalGroup>();

Kode ini mendefinisikan koleksi bernama Animals, di mana setiap item dalam koleksi adalah AnimalGroup objek. Setiap AnimalGroup objek terdiri dari nama, dan List<Animal> koleksi yang menentukan Animal objek dalam grup.

Data yang dikelompokkan kemudian dapat ditambahkan ke Animals koleksi:

Animals.Add(new AnimalGroup("Bears", new List<Animal>
{
    new Animal
    {
        Name = "American Black Bear",
        Location = "North America",
        Details = "Details about the bear go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/0/08/01_Schwarzbär.jpg"
    },
    new Animal
    {
        Name = "Asian Black Bear",
        Location = "Asia",
        Details = "Details about the bear go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG/180px-Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG"
    },
    // ...
}));

Animals.Add(new AnimalGroup("Monkeys", new List<Animal>
{
    new Animal
    {
        Name = "Baboon",
        Location = "Africa & Asia",
        Details = "Details about the monkey go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
    },
    new Animal
    {
        Name = "Capuchin Monkey",
        Location = "Central & South America",
        Details = "Details about the monkey go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Capuchin_Costa_Rica.jpg/200px-Capuchin_Costa_Rica.jpg"
    },
    new Animal
    {
        Name = "Blue Monkey",
        Location = "Central and East Africa",
        Details = "Details about the monkey go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/BlueMonkey.jpg/220px-BlueMonkey.jpg"
    },
    // ...
}));

Kode ini membuat dua grup dalam Animals koleksi. Yang pertama AnimalGroup diberi nama Bears, dan berisi List<Animal> kumpulan detail beruang. Yang kedua AnimalGroup diberi nama Monkeys, dan berisi List<Animal> kumpulan detail monyet.

ListView akan menampilkan data yang dikelompokkan, asalkan data telah dikelompokkan dengan benar, dengan mengatur IsGroupingEnabled properti ke true:

<ListView ItemsSource="{Binding Animals}"
          IsGroupingEnabled="True">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Grid Padding="10">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Image Grid.RowSpan="2"
                           Source="{Binding ImageUrl}"
                           Aspect="AspectFill"
                           HeightRequest="60"
                           WidthRequest="60" />
                    <Label Grid.Column="1"
                           Text="{Binding Name}"
                           FontAttributes="Bold" />
                    <Label Grid.Row="1"
                           Grid.Column="1"
                           Text="{Binding Location}"
                           FontAttributes="Italic"
                           VerticalOptions="End" />
                </Grid>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Kode C# yang setara adalah:

ListView listView = new ListView
{
    IsGroupingEnabled = true
};
listView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
// ...

Tampilan setiap item dalam ListView ditentukan dengan mengatur propertinya ItemTemplate ke DataTemplate. Untuk informasi selengkapnya, lihat Menentukan tampilan item.

Cuplikan layar berikut menunjukkan menampilkan data yang ListView dikelompokkan:

Cuplikan layar data yang dikelompokkan dalam ListView.

Catatan

Secara default, ListView akan menampilkan nama grup di header grup. Perilaku ini dapat diubah dengan menyesuaikan header grup.

Mengkustomisasi header grup

Tampilan setiap header grup dapat disesuaikan dengan mengatur ListView.GroupHeaderTemplate properti ke DataTemplate:

<ListView ItemsSource="{Binding Animals}"
          IsGroupingEnabled="True">
    <ListView.GroupHeaderTemplate>
        <DataTemplate>
            <ViewCell>
                <Label Text="{Binding Name}"
                       BackgroundColor="LightGray"
                       FontSize="18"
                       FontAttributes="Bold" />
            </ViewCell>
        </DataTemplate>
    </ListView.GroupHeaderTemplate>
    ...
</ListView>

Dalam contoh ini, setiap header grup diatur ke Label yang menampilkan nama grup, dan yang memiliki properti tampilan lain yang diatur. Cuplikan layar berikut menunjukkan header grup yang dikustomisasi:

Cuplikan layar header grup yang dikustomisasi di ListView.

Penting

Properti GroupHeaderTemplate ini saling eksklusif dengan GroupDisplayBinding properti. Oleh karena itu, kedua properti tidak boleh diatur.

Grup tanpa templat

ListView dapat menampilkan data yang dikelompokkan dengan benar tanpa mengatur ItemTemplate properti ke DataTemplate:

<ListView ItemsSource="{Binding Animals}"
          IsGroupingEnabled="true" />

Dalam skenario ini, data yang bermakna dapat ditampilkan dengan mengambil alih metode dalam jenis yang memodelkan ToString satu item, dan jenis yang memodelkan satu grup item.

Mengontrol pengguliran

ListView menentukan dua ScrollTo metode, yang menggulir item ke dalam tampilan. Salah satu kelebihan beban menggulir item yang ditentukan ke dalam tampilan, sementara yang lain menggulir item yang ditentukan dalam grup yang ditentukan ke dalam tampilan. Kedua kelebihan beban memiliki argumen tambahan yang memungkinkan posisi item yang tepat setelah gulir selesai ditentukan, dan apakah akan menganimasikan gulir.

ListViewScrollToRequested mendefinisikan peristiwa yang diaktifkan ketika salah ScrollTo satu metode dipanggil. Objek ScrollToRequestedEventArgs yang menyertai ScrollToRequested acara memiliki banyak properti, termasuk ShouldAnimate, , ElementMode, dan Position. Beberapa properti ini diatur dari argumen yang ditentukan dalam ScrollTo panggilan metode.

Selain itu, ListView menentukan Scrolled peristiwa yang diaktifkan untuk menunjukkan bahwa pengguliran terjadi. Objek ScrolledEventArgs yang menyertai Scrolled acara memiliki ScrollX properti dan ScrollY .

Mendeteksi pengguliran

ListViewScrolled menentukan peristiwa yang diaktifkan untuk menunjukkan bahwa pengguliran terjadi. Kelas ItemsViewScrolledEventArgs , yang mewakili objek yang menyertai Scrolled peristiwa, menentukan properti berikut:

  • ScrollX, dari jenis double, mewakili posisi X dari gulir
  • ScrollY, dari jenis double, mewakili posisi Y dari gulir.

Contoh XAML berikut menunjukkan ListView yang mengatur penanganan aktivitas untuk peristiwa:Scrolled

<ListView Scrolled="OnListViewScrolled">
    ...
</ListView>

Kode C# yang setara adalah:

ListView listView = new ListView();
listView.Scrolled += OnListViewScrolled;

Dalam contoh kode ini, OnListViewScrolled penanganan aktivitas dijalankan saat Scrolled peristiwa diaktifkan:

void OnListViewScrolled(object sender, ScrolledEventArgs e)
{
    // Custom logic
}

Penting

Peristiwa Scrolled diaktifkan untuk gulir yang dimulai pengguna, dan untuk gulir terprogram.

Menggulir item ke dalam tampilan

Metode menggulir ScrollTo item yang ditentukan ke dalam tampilan. ListView Mengingat objek bernama listView, contoh berikut menunjukkan cara menggulir item Monyet Belalai ke dalam tampilan:

MonkeysViewModel viewModel = BindingContext as MonkeysViewModel;
Monkey monkey = viewModel.Monkeys.FirstOrDefault(m => m.Name == "Proboscis Monkey");
listView.ScrollTo(monkey, ScrollToPosition.MakeVisible, true);

Atau, item dalam data yang dikelompokkan dapat digulir ke tampilan dengan menentukan item dan grup. Contoh berikut menunjukkan cara menggulir item Monyet Belalai di grup Monkeys ke dalam tampilan:

GroupedAnimalsViewModel viewModel = BindingContext as GroupedAnimalsViewModel;
AnimalGroup group = viewModel.Animals.FirstOrDefault(a => a.Name == "Monkeys");
Animal monkey = group.FirstOrDefault(m => m.Name == "Proboscis Monkey");
listView.ScrollTo(monkey, group, ScrollToPosition.MakeVisible, true);

Catatan

Peristiwa ScrollToRequested dipicu ketika ScrollTo metode dipanggil.

Menonaktifkan animasi gulir

Animasi gulir ditampilkan saat menggulir item ke dalam tampilan. Namun, animasi ini dapat dinonaktifkan dengan mengatur animated argumen ScrollTo metode ke false:

listView.ScrollTo(monkey, position: ScrollToPosition.MakeVisible, animate: false);

Mengontrol posisi gulir

Saat menggulir item ke dalam tampilan, posisi item yang tepat setelah gulir selesai dapat ditentukan dengan position argumen ScrollTo metode. Argumen ini menerima ScrollToPosition anggota enumerasi.

MakeVisible

Anggota ScrollToPosition.MakeVisible menunjukkan bahwa item harus digulir hingga terlihat dalam tampilan:

listView.ScrollTo(monkey, position: ScrollToPosition.MakeVisible, animate: true);

Mulai

Anggota ScrollToPosition.Start menunjukkan bahwa item harus digulir ke awal tampilan:

listView.ScrollTo(monkey, position: ScrollToPosition.Start, animate: true);

Pusat

Anggota ScrollToPosition.Center menunjukkan bahwa item harus digulir ke tengah tampilan:

listView.ScrollTo(monkey, position: ScrollToPosition.Center, animate: true);

Akhir

Anggota ScrollToPosition.End menunjukkan bahwa item harus digulir ke akhir tampilan:

listView.ScrollTo(monkey, position: ScrollToPosition.End, animate: true);

Visibilitas bilah gulir

ListViewHorizontalScrollBarVisibility menentukan dan VerticalScrollBarVisibility properti, yang didukung oleh properti yang dapat diikat. Properti ini mendapatkan atau mengatur ScrollBarVisibility nilai enumerasi yang mewakili kapan horizontal, atau vertikal, bilah gulir terlihat. Enumerasi ScrollBarVisibility menentukan anggota berikut:

  • Default menunjukkan perilaku bilah gulir default untuk platform, dan merupakan nilai default untuk HorizontalScrollBarVisibility properti dan VerticalScrollBarVisibility .
  • Always menunjukkan bahwa bilah gulir akan terlihat, bahkan ketika konten pas dalam tampilan.
  • Never menunjukkan bahwa bilah gulir tidak akan terlihat, meskipun konten tidak pas dalam tampilan.

Menambahkan menu konteks

ListView mendukung item menu konteks, yang didefinisikan sebagai MenuItem objek yang ditambahkan ke ViewCell.ContextActions koleksi di DataTemplate untuk setiap item:

<ListView x:Name="listView"
          ItemsSource="{Binding Monkeys}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <ViewCell.ContextActions>
                    <MenuItem Text="Favorite"
                              Command="{Binding Source={x:Reference listView}, Path=BindingContext.FavoriteCommand}"
                              CommandParameter="{Binding}" />
                    <MenuItem Text="Delete"
                              Command="{Binding Source={x:Reference listView}, Path=BindingContext.DeleteCommand}"
                              CommandParameter="{Binding}" />
                </ViewCell.ContextActions>

                ...
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Objek MenuItem diungkapkan ketika item di diklik ListView kanan:

Cuplikan layar item menu konteks CollectionView.

Untuk informasi selengkapnya tentang item menu, lihat Menampilkan item menu.

Tarik untuk menyegarkan

ListView mendukung penarikan untuk menyegarkan fungsionalitas, yang memungkinkan data ditampilkan untuk disegarkan dengan menarik ke bawah pada daftar item.

Untuk mengaktifkan tarik untuk menyegarkan, atur properti ke IsPullToRefreshEnabled true. Ketika refresh dipicu, ListView menaikkan Refreshing peristiwa, dan IsRefreshing properti akan diatur ke true. Kode yang diperlukan untuk me-refresh ListView konten kemudian harus dijalankan oleh handler untuk Refreshing peristiwa, atau oleh ICommand implementasi yang RefreshCommand dijalankan. Setelah di-refresh ListView , IsRefreshing properti harus diatur ke false, atau EndRefresh metode harus dipanggil pada ListView, untuk menunjukkan bahwa refresh selesai.

Contoh berikut menunjukkan ListView yang menggunakan tarik untuk menyegarkan:

<ListView ItemsSource="{Binding Animals}"
          IsPullToRefreshEnabled="true"
          RefreshCommand="{Binding RefreshCommand}"
          IsRefreshing="{Binding IsRefreshing}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                ...
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Dalam contoh ini, ketika pengguna memulai refresh, ICommand yang ditentukan oleh RefreshCommand properti dijalankan, yang harus menyegarkan item yang ditampilkan. Visualisasi refresh ditampilkan saat refresh terjadi, yang terdiri dari lingkaran kemajuan animasi. Nilai IsRefreshing properti menunjukkan status operasi refresh saat ini. Ketika refresh dipicu, properti ini akan secara otomatis beralih ke true. Setelah refresh selesai, Anda harus mengatur ulang properti ke false.