Anpassen der Darstellung eines ListView-Steuerelements mit Xamarin.Android
Die Darstellung eines ListView-Steuerelements wird durch das Layout der angezeigten Zeilen bestimmt. Verwenden Sie zum Ändern der Darstellung eines ListView
Zeilenlayouts ein anderes Zeilenlayout.
Integrierte Zeilenansichten
Es gibt zwölf integrierte Ansichten, auf die mit Android.Resource.Layout verwiesen werden kann:
TestListItem – Einzelne Textzeile mit minimaler Formatierung.
SimpleListItem1 – Einzelne Textzeile.
SimpleListItem2 – Zwei Textzeilen.
SimpleSelectableListItem – Einzelne Textzeile, die die Auswahl einzelner oder mehrerer Elemente unterstützt (in API-Ebene 11 hinzugefügt).
SimpleListItemActivated1 – Ähnlich wie SimpleListItem1, aber die Hintergrundfarbe gibt an, wann eine Zeile ausgewählt wird (hinzugefügt in API-Ebene 11).
SimpleListItemActivated2 – Ähnlich wie SimpleListItem2, aber die Hintergrundfarbe gibt an, wann eine Zeile ausgewählt ist (in API-Ebene 11 hinzugefügt).
SimpleListItemChecked – Zeigt Häkchen an, um die Auswahl anzugeben.
SimpleListItemMultipleChoice – Zeigt Kontrollkästchen an, um die Mehrfachauswahl anzugeben.
SimpleListItemSingleChoice – Zeigt Optionsfelder an, um sich gegenseitig ausschließende Auswahl anzuzeigen.
TwoLineListItem – Zwei Textzeilen.
ActivityListItem – Einzelne Textzeile mit einem Bild.
SimpleExpandableListItem – Gruppiert Zeilen nach Kategorien, und jede Gruppe kann erweitert oder reduziert werden.
Jede integrierte Zeilenansicht weist eine integrierte Formatvorlage auf. Diese Screenshots zeigen, wie jede Ansicht angezeigt wird:
Die BuiltInViews/HomeScreenAdapter.cs-Beispieldatei (in der BuiltInViews-Lösung ) enthält den Code, um die nicht erweiterbaren Listenelementbildschirme zu erzeugen. Die Ansicht wird in der GetView
Methode wie folgt festgelegt:
view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, null);
Die Eigenschaften der Ansicht können dann festgelegt werden, indem sie auf die Standardsteuerelement-IDs Text1
verweisen, Text2
und Icon
unter Android.Resource.Id
(legen Sie keine Eigenschaften fest, die die Ansicht nicht enthält oder eine Ausnahme ausgelöst wird):
view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = item.Heading;
view.FindViewById<TextView>(Android.Resource.Id.Text2).Text = item.SubHeading;
view.FindViewById<ImageView>(Android.Resource.Id.Icon).SetImageResource(item.ImageResourceId); // only use with ActivityListItem
Die BuiltInExpandableViews/ExpandableScreenAdapter.cs Beispieldatei (in der BuiltInViews-Lösung ) enthält den Code, um den SimpleExpandableListItem-Bildschirm zu erzeugen. Die Gruppenansicht wird in der GetGroupView
Methode wie folgt festgelegt:
view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleExpandableListItem1, null);
Die untergeordnete Ansicht wird in der GetChildView
Methode wie folgt festgelegt:
view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleExpandableListItem2, null);
Die Eigenschaften für die Gruppenansicht und die untergeordnete Ansicht können dann durch Verweisen auf die Standard Text1
- und Text2
Steuerelement-IDs wie oben dargestellt festgelegt werden. Der Screenshot des SimpleExpandableListItem (siehe oben) enthält ein Beispiel für eine einzeilige Gruppenansicht (SimpleExpandableListItem1) und eine zweizeilige untergeordnete Ansicht (SimpleExpandableListItem2). Alternativ kann die Gruppenansicht für zwei Zeilen (SimpleExpandableListItem2) konfiguriert werden, und die untergeordnete Ansicht kann für eine Zeile (SimpleExpandableListItem1) konfiguriert werden, oder sowohl die Gruppenansicht als auch die untergeordnete Ansicht können dieselbe Anzahl von Zeilen aufweisen.
Accessories
Zeilen können Zubehör rechts neben der Ansicht hinzugefügt werden, um den Auswahlzustand anzugeben:
SimpleListItemChecked – Erstellt eine Einzelauswahlliste mit einem Häkchen als Indikator.
SimpleListItemSingleChoice – Erstellt Optionsfeld-Typlisten, bei denen nur eine Auswahl möglich ist.
SimpleListItemMultipleChoice – Erstellt Kontrollkästchentyplisten, in denen mehrere Auswahlmöglichkeiten möglich sind.
Das oben genannte Zubehör wird in den folgenden Bildschirmen in ihrer jeweiligen Reihenfolge dargestellt:
Um eins dieser Zubehörteile anzuzeigen, übergeben Sie die erforderliche Layoutressourcen-ID an den Adapter, und legen Sie dann den Auswahlstatus für die erforderlichen Zeilen manuell fest. Diese Codezeile zeigt, wie Sie eins Adapter
der folgenden Layouts erstellen und zuweisen:
ListAdapter = new ArrayAdapter<String>(this, Android.Resource.Layout.SimpleListItemChecked, items);
Der ListView
selbst unterstützt verschiedene Auswahlmodi, unabhängig vom angezeigten Zubehör. Um Verwirrung zu vermeiden, verwenden Sie Single
den Auswahlmodus mit SingleChoice
Zubehör und dem Checked
Modus Multiple
mit dem MultipleChoice
Stil. Der Auswahlmodus wird durch die ChoiceMode
Eigenschaft der ListView
.
Behandeln der API-Ebene
In früheren Versionen von Xamarin.Android wurden Enumerationen als ganzzahlige Eigenschaften implementiert. Die neueste Version hat die richtigen .NET-Enumerationstypen eingeführt, wodurch es viel einfacher ist, die potenziellen Optionen zu ermitteln.
Je nachdem, auf welche API-Ebene Sie abzielen, ChoiceMode
handelt es sich entweder um eine ganze Zahl oder eine Enumeration. Die Beispieldatei AccessoryViews/HomeScreen.cs hat einen Block auskommentiert, wenn Sie die Gingerbread-API als Ziel festlegen möchten:
// For targeting Gingerbread the ChoiceMode is an int, otherwise it is an
// enumeration.
lv.ChoiceMode = Android.Widget.ChoiceMode.Single; // 1
//lv.ChoiceMode = Android.Widget.ChoiceMode.Multiple; // 2
//lv.ChoiceMode = Android.Widget.ChoiceMode.None; // 0
// Use this block if targeting Gingerbread or lower
/*
lv.ChoiceMode = 1; // Single
//lv.ChoiceMode = 0; // none
//lv.ChoiceMode = 2; // Multiple
//lv.ChoiceMode = 3; // MultipleModal
*/
Programmgesteuertes Auswählen von Elementen
Das manuelle Festlegen, welche Elemente "ausgewählt" sind, erfolgt mit der SetItemChecked
Methode (es kann mehrmals für mehrfache Auswahl aufgerufen werden):
// Set the initially checked row ("Fruits")
lv.SetItemChecked(1, true);
Der Code muss auch einzelne Auswahlen anders erkennen als mehrfache Auswahlen. Um zu bestimmen, welche Zeile im Single
Modus ausgewählt wurde, verwenden Sie die CheckedItemPosition
ganzzahlige Eigenschaft:
FindViewById<ListView>(Android.Resource.Id.List).CheckedItemPosition
Um zu ermitteln, welche Zeilen im Multiple
Modus ausgewählt wurden, müssen Sie die CheckedItemPositions
SparseBooleanArray
Schleife durchlaufen. Ein geringes Array ist wie ein Wörterbuch, das nur Einträge enthält, bei denen der Wert geändert wurde. Daher müssen Sie das gesamte Array true
durchlaufen, um nach Werten zu suchen, um zu wissen, was in der Liste ausgewählt wurde, wie im folgenden Codeausschnitt veranschaulicht:
var sparseArray = FindViewById<ListView>(Android.Resource.Id.List).CheckedItemPositions;
for (var i = 0; i < sparseArray.Size(); i++ )
{
Console.Write(sparseArray.KeyAt(i) + "=" + sparseArray.ValueAt(i) + ",");
}
Console.WriteLine();
Erstellen von benutzerdefinierten Zeilenlayouts
Die vier integrierten Zeilenansichten sind sehr einfach. Um komplexere Layouts (z. B. eine Liste von E-Mails oder Tweets oder Kontaktinformationen) anzuzeigen, ist eine benutzerdefinierte Ansicht erforderlich. Benutzerdefinierte Ansichten werden im Allgemeinen als AXML-Dateien im Verzeichnis "Ressourcen/Layout " deklariert und dann mithilfe ihrer Ressourcen-ID von einem benutzerdefinierten Adapter geladen. Die Ansicht kann eine beliebige Anzahl von Anzeigeklassen (z. B. TextViews, ImageViews und andere Steuerelemente) mit benutzerdefinierten Farben, Schriftarten und Layout enthalten.
Dieses Beispiel unterscheidet sich von den vorherigen Beispielen auf verschiedene Arten:
Erbt von
Activity
, nichtListActivity
. Sie können Zeilen für beliebigeListView
Steuerelemente anpassen, andere Steuerelemente können jedoch auch in einActivity
Layout aufgenommen werden (z. B. Überschriften, Schaltflächen oder andere Benutzeroberflächenelemente). In diesem Beispiel wird oberhalb derListView
zu veranschaulichenden Überschrift eine Überschrift hinzugefügt.Erfordert eine AXML-Layoutdatei für den Bildschirm; in den vorherigen Beispielen
ListActivity
ist keine Layoutdatei erforderlich. Diese AXML enthält eineListView
Steuerelementdeklaration.Erfordert eine AXML-Layoutdatei zum Rendern jeder Zeile. Diese AXML-Datei enthält die Text- und Bildsteuerelemente mit benutzerdefinierten Schriftart- und Farbeinstellungen.
Verwendet eine optionale benutzerdefinierte Selektor-XML-Datei, um die Darstellung der Zeile festzulegen, wenn sie ausgewählt ist.
Die
Adapter
Implementierung gibt ein benutzerdefiniertes Layout aus derGetView
Außerkraftsetzung zurück.ItemClick
muss anders deklariert werden (ein Ereignishandler wird anstelle einer AußerkraftsetzungOnListItemClick
angefügtListView.ItemClick
ListActivity
).
Diese Änderungen sind unten detailliert dargestellt, beginnend mit dem Erstellen der Ansicht der Aktivität und der benutzerdefinierten Zeilenansicht und anschließender Abdeckung der Änderungen am Adapter und der Aktivität, um sie zu rendern.
Hinzufügen einer ListView zu einem Aktivitätslayout
Da HomeScreen
sie nicht mehr über eine Standardansicht erbt ListActivity
, muss daher eine Layout-AXML-Datei für die HomeScreen-Ansicht erstellt werden. In diesem Beispiel verfügt die Ansicht über eine Überschrift (mit einer TextView
) und eine ListView
zum Anzeigen von Daten. Das Layout ist in der Datei "Resources/Layout/HomeScreen.axml " definiert, die hier gezeigt wird:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/Heading"
android:text="Vegetable Groups"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00000000"
android:textSize="30dp"
android:textColor="#FF267F00"
android:textStyle="bold"
android:padding="5dp"
/>
<ListView android:id="@+id/List"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#FFDAFF7F"
/>
</LinearLayout>
Der Vorteil der Verwendung eines Activity
benutzerdefinierten Layouts (anstelle eines ListActivity
) liegt darin, dem Bildschirm zusätzliche Steuerelemente hinzuzufügen, z. B. die Überschrift TextView
in diesem Beispiel.
Erstellen eines benutzerdefinierten Zeilenlayouts
Eine weitere AXML-Layoutdatei ist erforderlich, um das benutzerdefinierte Layout für jede Zeile zu enthalten, die in der Listenansicht angezeigt wird. In diesem Beispiel enthält die Zeile einen grünen Hintergrund, braunen Text und rechts ausgerichtetes Bild. Das Android-XML-Markup zum Deklarieren dieses Layouts wird in "Resources/Layout/CustomView.axml" beschrieben:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#FFDAFF7F"
android:padding="8dp">
<LinearLayout android:id="@+id/Text"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dip">
<TextView
android:id="@+id/Text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF7F3300"
android:textSize="20dip"
android:textStyle="italic"
/>
<TextView
android:id="@+id/Text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14dip"
android:textColor="#FF267F00"
android:paddingLeft="100dip"
/>
</LinearLayout>
<ImageView
android:id="@+id/Image"
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="5dp"
android:src="@drawable/icon"
android:layout_alignParentRight="true" />
</RelativeLayout >
Während ein benutzerdefiniertes Zeilenlayout viele verschiedene Steuerelemente enthalten kann, kann die Bildlaufleistung durch komplexe Designs und die Verwendung von Bildern beeinflusst werden (insbesondere, wenn sie über das Netzwerk geladen werden müssen). Weitere Informationen zur Behandlung von Leistungsproblemen beim Scrollen finden Sie im Google-Artikel.
Verweisen auf eine benutzerdefinierte Zeilenansicht
Die Implementierung des benutzerdefinierten Adapterbeispiels ist in HomeScreenAdapter.cs
. Die Schlüsselmethode ist GetView
der Ort, an dem die benutzerdefinierte AXML mithilfe der Ressourcen-ID Resource.Layout.CustomView
geladen wird, und legt dann Eigenschaften für jedes der Steuerelemente in der Ansicht fest, bevor sie zurückgegeben wird. Die vollständige Adapterklasse wird angezeigt:
public class HomeScreenAdapter : BaseAdapter<TableItem> {
List<TableItem> items;
Activity context;
public HomeScreenAdapter(Activity context, List<TableItem> items)
: base()
{
this.context = context;
this.items = items;
}
public override long GetItemId(int position)
{
return position;
}
public override TableItem this[int position]
{
get { return items[position]; }
}
public override int Count
{
get { return items.Count; }
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = items[position];
View view = convertView;
if (view == null) // no view to re-use, create new
view = context.LayoutInflater.Inflate(Resource.Layout.CustomView, null);
view.FindViewById<TextView>(Resource.Id.Text1).Text = item.Heading;
view.FindViewById<TextView>(Resource.Id.Text2).Text = item.SubHeading;
view.FindViewById<ImageView>(Resource.Id.Image).SetImageResource(item.ImageResourceId);
return view;
}
}
Verweisen auf die benutzerdefinierte ListView in der Aktivität
Da die HomeScreen
Klasse jetzt von Activity
erbt, wird ein ListView
Feld in der Klasse deklariert, um einen Verweis auf das im AXML deklarierte Steuerelement zu enthalten:
ListView listView;
Die Klasse muss dann das benutzerdefinierte Layout "AXML" der Aktivität mithilfe der SetContentView
Methode laden. Anschließend wird das ListView
Steuerelement im Layout erstellt und zugewiesen und dem Klickhandler zugewiesen. Der Code für die OnCreate-Methode wird hier gezeigt:
SetContentView(Resource.Layout.HomeScreen); // loads the HomeScreen.axml as this activity's view
listView = FindViewById<ListView>(Resource.Id.List); // get reference to the ListView in the layout
// populate the listview with data
listView.Adapter = new HomeScreenAdapter(this, tableItems);
listView.ItemClick += OnListItemClick; // to be defined
Schließlich muss der ItemClick
Handler definiert werden. In diesem Fall wird nur eine Toast
Meldung angezeigt:
void OnListItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
var listView = sender as ListView;
var t = tableItems[e.Position];
Android.Widget.Toast.MakeText(this, t.Heading, Android.Widget.ToastLength.Short).Show();
}
Der resultierende Bildschirm sieht wie folgt aus:
Anpassen der Zeilenauswahlfarbe
Wenn eine Zeile berührt wird, sollte sie für Benutzerfeedback hervorgehoben werden. Wenn eine benutzerdefinierte Ansicht als Hintergrundfarbe wie CustomView.axml angibt, überschreibt sie auch die Auswahlherhebung. Diese Codezeile in CustomView.axml legt den Hintergrund auf Hellgrün fest, bedeutet aber auch, dass es keinen visuellen Indikator gibt, wenn die Zeile berührt wird:
android:background="#FFDAFF7F"
Um das Hervorhebungsverhalten erneut zu aktivieren und die verwendete Farbe anzupassen, legen Sie stattdessen das Hintergrundattribute auf eine benutzerdefinierte Auswahl fest. Die Auswahl deklariert sowohl die Standardhintergrundfarbe als auch die Hervorhebungsfarbe. Die Datei "Resources/Drawable/CustomSelector.xml " enthält die folgende Deklaration:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false"
android:state_selected="false"
android:drawable="@color/cellback" />
<item android:state_pressed="true" >
<shape>
<gradient
android:startColor="#E77A26"
android:endColor="#E77A26"
android:angle="270" />
</shape>
</item>
<item android:state_selected="true"
android:state_pressed="false"
android:drawable="@color/cellback" />
</selector>
Um auf die benutzerdefinierte Auswahl zu verweisen, ändern Sie das Hintergrundattribute in CustomView.axml in:
android:background="@drawable/CustomSelector"
Eine ausgewählte Zeile und die entsprechende Toast
Nachricht sieht nun wie folgt aus:
Verhindern von Flackern in benutzerdefinierten Layouts
Android versucht, die Leistung des ListView
Bildlaufs zu verbessern, indem Layoutinformationen zwischengespeichert werden. Wenn Sie über lange Bildlauflisten mit Daten verfügen, sollten Sie auch die Eigenschaft für die android:cacheColorHint
ListView
Deklaration in der AXML-Definition der Aktivität festlegen (auf denselben Farbwert wie der Hintergrund des benutzerdefinierten Zeilenlayouts). Wenn dieser Hinweis nicht eingeschlossen werden kann, kann ein "Flackern" auftreten, wenn der Benutzer durch eine Liste mit benutzerdefinierten Zeilenhintergrundfarben scrollt.