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:
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:
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 ArrayAdapter
dengan 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:
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:
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 sebagaiJava.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.