Bagikan melalui


Mengisi Xamarin.Android ListView dengan data

Untuk menambahkan baris ke, ListView Anda perlu menambahkannya ke tata letak Anda dan menerapkan IListAdapter dengan metode yang ListView dipanggil untuk mengisi dirinya sendiri. Android menyertakan kelas dan ArrayAdapter bawaan ListActivity yang dapat Anda gunakan tanpa menentukan XML atau kode tata letak kustom apa pun. Kelas ListActivity secara otomatis membuat ListView dan mengekspos ListAdapter properti untuk menyediakan tampilan baris yang akan ditampilkan melalui adaptor.

Adaptor bawaan mengambil ID sumber daya tampilan sebagai parameter yang digunakan untuk setiap baris. Anda dapat menggunakan sumber daya bawaan seperti sumber daya tersebut Android.Resource.Layout sehingga Anda tidak perlu menulis sumber daya Anda sendiri.

Menggunakan String ListActivity dan ArrayAdapter<>

Contoh BasicTable/HomeScreen.cs menunjukkan cara menggunakan kelas ini untuk menampilkan ListView hanya dalam beberapa baris kode:

[Activity(Label = "BasicTable", MainLauncher = true, Icon = "@drawable/icon")]
public class HomeScreen : ListActivity {
   string[] items;
   protected override void OnCreate(Bundle bundle)
   {
       base.OnCreate(bundle);
       items = new string[] { "Vegetables","Fruits","Flower Buds","Legumes","Bulbs","Tubers" };
       ListAdapter = new ArrayAdapter<String>(this, Android.Resource.Layout.SimpleListItem1, items);
   }
}

Menangani klik baris

Biasanya juga ListView akan memungkinkan pengguna menyentuh baris untuk melakukan beberapa tindakan (seperti memutar lagu, atau memanggil kontak, atau menampilkan layar lain). Untuk menanggapi sentuhan pengguna, perlu ada satu metode lagi yang diterapkan dalam ListActivity - OnListItemClick seperti ini:

Cuplikan layar SimpleListItem

protected override void OnListItemClick(ListView l, View v, int position, long id)
{
   var t = items[position];
   Android.Widget.Toast.MakeText(this, t, Android.Widget.ToastLength.Short).Show();
}

Sekarang pengguna dapat menyentuh baris dan Toast pemberitahuan akan muncul:

Cuplikan layar Toast yang muncul saat baris disentuh

Menerapkan ListAdapter

ArrayAdapter<string> sangat bagus karena kesederhanaannya, tetapi sangat terbatas. Namun, sering kali Anda memiliki kumpulan entitas bisnis, bukan hanya string yang ingin Anda ikat. Misalnya, jika data Anda terdiri dari kumpulan kelas Karyawan, maka Anda mungkin ingin daftar hanya menampilkan nama setiap karyawan. Untuk menyesuaikan perilaku ListView untuk mengontrol data apa yang ditampilkan, Anda harus menerapkan subkelas mengesampingkan BaseAdapter empat item berikut:

  • Hitung – Untuk memberi tahu kontrol berapa banyak baris dalam data.

  • GetView – Untuk mengembalikan Tampilan untuk setiap baris, diisi dengan data. Metode ini memiliki parameter untuk ListView meneruskan baris yang sudah ada dan tidak digunakan untuk digunakan kembali.

  • GetItemId – Mengembalikan pengidentifikasi baris (biasanya nomor baris, meskipun bisa menjadi nilai panjang yang Anda suka).

  • pengindeks ini[int] - Untuk mengembalikan data yang terkait dengan nomor baris tertentu.

Contoh kode di BasicTableAdapter/HomeScreenAdapter.cs menunjukkan cara subkelas BaseAdapter:

public class HomeScreenAdapter : BaseAdapter<string> {
   string[] items;
   Activity context;
   public HomeScreenAdapter(Activity context, string[] items) : base() {
       this.context = context;
       this.items = items;
   }
   public override long GetItemId(int position)
  {
       return position;
   }
   public override string this[int position] {  
       get { return items[position]; }
   }
   public override int Count {
       get { return items.Length; }
   }
   public override View GetView(int position, View convertView, ViewGroup parent)
   {
       View view = convertView; // re-use an existing view, if one is available
      if (view == null) // otherwise create a new one
           view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, null);
       view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = items[position];
       return view;
   }
}

Menggunakan adaptor kustom

Menggunakan adaptor kustom mirip ArrayAdapterdengan bawaan , meneruskan context dan string[] nilai yang akan ditampilkan:

ListAdapter = new HomeScreenAdapter(this, items);

Karena contoh ini menggunakan tata letak baris yang sama (SimpleListItem1) aplikasi yang dihasilkan akan terlihat identik dengan contoh sebelumnya.

Tampilan baris digunakan kembali

Dalam contoh ini hanya ada enam item. Karena layar dapat pas delapan, tidak diperlukan penggunaan kembali baris. Namun, ketika menampilkan ratusan atau ribuan baris, itu akan menjadi buang-buang memori untuk membuat ratusan atau ribuan View objek ketika hanya delapan pas di layar pada satu waktu. Untuk menghindari situasi ini, ketika baris menghilang dari layar tampilannya ditempatkan dalam antrean untuk digunakan kembali. Saat pengguna menggulir, ListView panggilan GetView untuk meminta tampilan baru ditampilkan - jika tersedia, itu melewati tampilan yang tidak digunakan dalam convertView parameter. Jika nilai ini null, maka kode Anda harus membuat instans tampilan baru, jika tidak, Anda dapat mengatur ulang properti objek tersebut dan menggunakannya kembali.

Metode GetView harus mengikuti pola ini untuk menggunakan kembali tampilan baris:

public override View GetView(int position, View convertView, ViewGroup parent)
{
   View view = convertView; // re-use an existing view, if one is supplied
   if (view == null) // otherwise create a new one
       view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, null);
   // set view properties to reflect data for the given row
   view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = items[position];
   // return the view, populated with data, for display
   return view;
}

Implementasi adaptor kustom harus selalu menggunakan convertView kembali objek sebelum membuat tampilan baru untuk memastikan mereka tidak kehabisan memori saat menampilkan daftar panjang.

Beberapa implementasi adaptor (seperti CursorAdapter) tidak memiliki GetView metode, melainkan memerlukan dua metode NewView yang berbeda dan BindView yang memberlakukan penggunaan kembali baris dengan memisahkan tanggung jawab GetView menjadi dua metode. Ada CursorAdapter contoh nanti dalam dokumen.

Mengaktifkan pengguliran cepat

Fast Scrolling membantu pengguna untuk menggulir daftar panjang dengan menyediakan 'handel' tambahan yang bertindak sebagai bilah gulir untuk langsung mengakses bagian dari daftar. Cuplikan layar ini menunjukkan handel gulir cepat:

Cuplikan layar pengguliran cepat dengan handel gulir

Menyebabkan handel penggulir cepat muncul sesering mengatur FastScrollEnabled properti ke true:

ListView.FastScrollEnabled = true;

Menambahkan indeks bagian

Indeks bagian memberikan umpan balik tambahan bagi pengguna ketika mereka bergulir cepat melalui daftar panjang - ini menunjukkan 'bagian' mana yang telah mereka gulir. Untuk menyebabkan indeks bagian muncul, subkelas Adapter harus mengimplementasikan ISectionIndexer antarmuka untuk menyediakan teks indeks tergantung pada baris yang ditampilkan:

Cuplikan layar H muncul di atas bagian yang dimulai dengan H

Untuk mengimplementasikan ISectionIndexer , Anda perlu menambahkan tiga metode ke adaptor:

  • GetSections – Menyediakan daftar lengkap judul indeks bagian yang dapat ditampilkan. Metode ini memerlukan array Objek Java sehingga kode perlu membuat Java.Lang.Object[] dari koleksi .NET. Dalam contoh kami, ia mengembalikan daftar karakter awal dalam daftar sebagai Java.Lang.String .

  • GetPositionForSection – Mengembalikan posisi baris pertama untuk indeks bagian tertentu.

  • GetSectionForPosition – Mengembalikan indeks bagian yang akan ditampilkan untuk baris tertentu.

File contoh SectionIndex/HomeScreenAdapter.cs mengimplementasikan metode tersebut, dan beberapa kode tambahan dalam konstruktor. Konstruktor membangun indeks bagian dengan mengulangi setiap baris dan mengekstrak karakter pertama judul (item harus sudah diurutkan agar ini berfungsi).

alphaIndex = new Dictionary<string, int>();
for (int i = 0; i < items.Length; i++) { // loop through items
   var key = items[i][0].ToString();
   if (!alphaIndex.ContainsKey(key))
       alphaIndex.Add(key, i); // add each 'new' letter to the index
}
sections = new string[alphaIndex.Keys.Count];
alphaIndex.Keys.CopyTo(sections, 0); // convert letters list to string[]

// Interface requires a Java.Lang.Object[], so we create one here
sectionsObjects = new Java.Lang.Object[sections.Length];
for (int i = 0; i < sections.Length; i++) {
   sectionsObjects[i] = new Java.Lang.String(sections[i]);
}

Dengan struktur data yang dibuat, ISectionIndexer metodenya sangat sederhana:

public Java.Lang.Object[] GetSections()
{
   return sectionsObjects;
}
public int GetPositionForSection(int section)
{
   return alphaIndexer[sections[section]];
}
public int GetSectionForPosition(int position)
{   // this method isn't called in this example, but code is provided for completeness
    int prevSection = 0;
    for (int i = 0; i < sections.Length; i++)
    {
        if (GetPositionForSection(i) > position)
        {
            break;
        }
        prevSection = i;
    }
    return prevSection;
}

Judul indeks bagian Anda tidak perlu memetakan 1:1 ke bagian Anda yang sebenarnya. Inilah sebabnya mengapa GetPositionForSection metode ada. GetPositionForSection memberi Anda kesempatan untuk memetakan indeks apa pun yang ada dalam daftar indeks Anda ke bagian apa pun yang ada dalam tampilan daftar Anda. Misalnya, Anda mungkin memiliki "z" dalam indeks Anda, tetapi Anda mungkin tidak memiliki bagian tabel untuk setiap huruf, jadi alih-alih pemetaan "z" ke 26, itu dapat memetakan ke 25 atau 24, atau indeks bagian apa pun "z" harus dipetakan.