Xamarin.Android ListView'ı verilerle doldurma
'a ListView
satır eklemek için, bunu düzeninize eklemeniz ve kendisini doldurmak için çağıran ListView
yöntemlerle bir IListAdapter
uygulamanız gerekir. Android, herhangi bir özel düzen XML'i ListActivity
veya kodu tanımlamadan kullanabileceğiniz yerleşik ve ArrayAdapter
sınıflar içerir. ListActivity
sınıfı otomatik olarak bir ListView
oluşturur ve bir bağdaştırıcı aracılığıyla görüntülenecek satır görünümlerini sağlamak için bir ListAdapter
özelliği kullanıma sunar.
Yerleşik bağdaştırıcılar, her satır için kullanılan bir parametre olarak bir görünüm kaynak kimliğini alır. Kendi kaynaklarınızı yazmanız gerekmeyecek şekilde içindekiler Android.Resource.Layout
gibi yerleşik kaynakları kullanabilirsiniz.
ListActivity ve ArrayAdapter<Dizesini Kullanma>
BasicTable/HomeScreen.cs örneği, yalnızca birkaç kod satırı içinde görüntülemek ListView
için bu sınıfların nasıl kullanılacağını gösterir:
[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);
}
}
Satır tıklamalarını işleme
Genellikle, ListView
kullanıcının bir satıra dokunarak bazı eylemler gerçekleştirmesine (şarkı çalma, kişiyi arama veya başka bir ekran gösterme gibi) izin verir. Kullanıcı dokunuşlarına yanıt vermek için aşağıdaki gibi içinde uygulanan ListActivity
OnListItemClick
bir yöntem daha olmalıdır:
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();
}
Artık kullanıcı bir satıra dokunabilir ve bir Toast
uyarı görüntülenir:
ListAdapter Uygulama
ArrayAdapter<string>
basitliği nedeniyle harikadır, ancak son derece sınırlıdır. Ancak, çoğu zaman yalnızca bağlamak istediğiniz dizeler yerine iş varlıklarından oluşan bir koleksiyonunuz olur.
Örneğin, verileriniz bir Çalışan sınıfları koleksiyonundan oluşuyorsa, listenin yalnızca her çalışanın adlarını görüntülemesini isteyebilirsiniz. Hangi verilerin görüntüleneceğini denetlemek üzere bir ListView
öğesinin davranışını özelleştirmek için aşağıdaki dört öğeyi geçersiz kılmanın bir alt sınıfını BaseAdapter
uygulamanız gerekir:
Count : Denetime verilerde kaç satır olduğunu söylemek için.
GetView : Her satır için verilerle doldurulmuş bir Görünüm döndürmek için. Bu yöntem, yeniden kullanım için
ListView
var olan, kullanılmayan bir satırı geçirmek için parametresine sahiptir.GetItemId : Bir satır tanımlayıcısı döndürür (genellikle satır numarasıdır, ancak istediğiniz herhangi bir uzun değer olabilir).
this[int] indexer – Belirli bir satır numarasıyla ilişkili verileri döndürmek için.
BasicTableAdapter/HomeScreenAdapter.cs'daki örnek kod, alt sınıfını BaseAdapter
gösterir:
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;
}
}
Özel bağdaştırıcı kullanma
Özel bağdaştırıcının kullanılması, ArrayAdapter
yerleşik öğesine benzer ve görüntülenecek değerleri iletir context
string[]
:
ListAdapter = new HomeScreenAdapter(this, items);
Bu örnek aynı satır düzenini (SimpleListItem1
) kullandığından, sonuçta elde edilen uygulama önceki örnekle aynı görünür.
Satır görünümünü yeniden kullanma
Bu örnekte yalnızca altı öğe vardır. Ekran sekize sığabildiğinden, satır yeniden kullanılması gerekmez. Bununla birlikte, yüzlerce veya binlerce satır görüntülerken, aynı anda ekrana yalnızca sekiz tane sığdığında yüzlerce veya binlerce View
nesne oluşturmak bellek kaybı olur. Bu durumu önlemek için, bir satır ekrandan kaybolduğunda görünümü yeniden kullanmak üzere bir kuyruğa yerleştirilir. Kullanıcı kaydırılırken, yeni görünümlerin ListView
görüntülenmesini isteme çağrısı GetView
yapılır; varsa parametresinde convertView
kullanılmayan bir görünüm geçirir. Bu değer null ise kodunuz yeni bir görünüm örneği oluşturmalıdır, aksi takdirde bu nesnenin özelliklerini yeniden ayarlayabilir ve yeniden kullanabilirsiniz.
Yöntem, GetView
satır görünümlerini yeniden kullanmak için bu deseni izlemelidir:
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;
}
Özel bağdaştırıcı uygulamaları, uzun listeleri görüntülerken belleğin convertView
bitmediğinden emin olmak için yeni görünümler oluşturmadan önce nesneyi her zaman yeniden kullanmalıdır.
Bazı bağdaştırıcı uygulamalarının CursorAdapter
(örneğin, ) bir GetView
yöntemi yoktur, bunun yerine iki farklı yöntem NewView
gerektirir ve BindView
öğesinin sorumluluklarını GetView
iki yönteme ayırarak satır yeniden kullanımını zorlar. Belgenin ilerleyen bölümlerinde bir CursorAdapter
örnek verilmiştir.
Hızlı kaydırmayı etkinleştirme
Hızlı Kaydırma, kullanıcının listenin bir bölümüne doğrudan erişmek için kaydırma çubuğu işlevi gören ek bir 'tanıtıcı' sağlayarak uzun listeleri kaydırmasına yardımcı olur. Bu ekran görüntüsü hızlı kaydırma tutamacını gösterir:
Hızlı kaydırma tutamacın görünmesine neden olmak, özelliğini true
olarak ayarlamak FastScrollEnabled
kadar basittir:
ListView.FastScrollEnabled = true;
Bölüm dizini ekleme
Bölüm dizini, kullanıcılar uzun bir listede hızlı bir şekilde gezinirken kullanıcılara ek geri bildirim sağlar; hangi 'bölüme' kaydırıldıklarını gösterir. Bölüm dizininin görünmesine neden olmak için Bağdaştırıcı alt sınıfının, görüntülenen satırlara bağlı olarak dizin metnini sağlamak için arabirimini uygulaması ISectionIndexer
gerekir:
Uygulamak ISectionIndexer
için bir bağdaştırıcıya üç yöntem eklemeniz gerekir:
GetSections – Görüntülenebilen bölüm dizini başlıklarının tam listesini sağlar. Bu yöntem bir Java Nesneleri dizisi gerektirdiğinden kodun bir .NET koleksiyonundan bir
Java.Lang.Object[]
oluşturması gerekir. Bizim örneğimizde listedeki ilk karakterlerin listesini olarakJava.Lang.String
döndürür.GetPositionForSection : Belirli bir bölüm dizini için ilk satır konumunu döndürür.
GetSectionForPosition : Belirli bir satır için görüntülenecek bölüm dizinini döndürür.
Örnek SectionIndex/HomeScreenAdapter.cs
dosya bu yöntemleri ve oluşturucuda bazı ek kodları uygular. Oluşturucu, her satırda döngü yaparak ve başlığın ilk karakterini ayıklayarak bölüm dizinini oluşturur (bunun çalışması için öğeler zaten sıralanmalıdır).
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]);
}
Oluşturulan veri yapıları ile ISectionIndexer
yöntemler çok basittir:
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;
}
Bölüm dizini başlıklarınızın 1:1'i gerçek bölümlerinizle eşlemesi gerekmez. Yöntemin GetPositionForSection
mevcut olmasının nedeni budur.
GetPositionForSection
, dizin listenizdeki tüm dizinleri liste görünümünüzdeki bölümlere eşleme fırsatı verir. Örneğin, dizininizde bir "z" olabilir, ancak her harf için bir tablo bölümünüz olmayabilir, bu nedenle 26 ile "z" eşlemesi yerine 25 veya 24'e veya "z" bölüm dizininin eşlemesi gereken bölüm dizinine eşlenebilir.