Eine gut gestaltete benutzerdefinierte Ansicht ist wie jede andere gut gestaltete Klasse. Sie kapselt eine bestimmte Reihe von Funktionen mit einer einfachen Schnittstelle, nutzt CPU und Arbeitsspeicher effizient usw. Eine benutzerdefinierte Ansicht muss nicht nur eine gut gestaltete Klasse sein, sondern auch die folgenden Anforderungen erfüllen:
- Android-Standards entsprechen
- Benutzerdefinierte formatierbare Attribute bereitstellen, die mit Android-XML-Layouts funktionieren
- Barrierefreiheitsereignisse senden
- Mit mehreren Android-Plattformen kompatibel sein
Das Android-Framework bietet eine Reihe von Basisklassen und XML-Tags, mit denen Sie eine Ansicht erstellen können, die alle diese Anforderungen erfüllt. In dieser Lektion wird beschrieben, wie Sie mit dem Android-Framework die Kern Funktionen einer Ansicht Klasse erstellen.
Weitere Informationen finden Sie unter Benutzerdefinierte Ansichtskomponenten.
Unterklasse einer Ansicht
Alle im Android-Framework definierten Ansichtsklassen erweitern
View. Ihre
benutzerdefinierte Ansicht kann auch
direkt View erweitern. Sie können aber auch
Zeit sparen, indem Sie eine der
vorhandenen Ansichts
unterklassen wie Button erweitern.
Damit Android Studio mit Ihrer Ansicht interagieren kann, müssen Sie mindestens einen Konstruktor angeben, der ein Context- und ein AttributeSet-Objekt als Parameter akzeptiert.
Mit diesem Konstruktor kann der Layouteditor eine Instanz Ihrer Ansicht erstellen und bearbeiten.
Kotlin
class PieChart(context: Context, attrs: AttributeSet) : View(context, attrs)
Java
class PieChart extends View { public PieChart(Context context, AttributeSet attrs) { super(context, attrs); } }
Benutzerdefinierte Attribute definieren
Wenn Sie Ihrer Benutzeroberfläche eine integrierte View hinzufügen möchten, geben Sie sie in einem XML-Element an und steuern Sie ihr Aussehen und Verhalten mit Elementattributen. Sie können auch benutzerdefinierte Ansichten mit XML hinzufügen und formatieren. So aktivieren Sie dieses Verhalten in Ihrer benutzerdefinierten Ansicht:
- Definieren Sie benutzerdefinierte Attribute für Ihre Ansicht in einem
<declare-styleable>Ressourcenelement. - Geben Sie Werte für die Attribute in Ihrem XML-Layout an.
- Rufen Sie Attributwerte zur Laufzeit ab.
- Wenden Sie die abgerufenen Attributwerte auf Ihre Ansicht an.
In diesem Abschnitt wird beschrieben, wie Sie benutzerdefinierte Attribute definieren und ihre Werte angeben. Im nächsten Abschnitt wird beschrieben, wie Sie die Werte zur Laufzeit abrufen und anwenden.
Wenn Sie benutzerdefinierte Attribute definieren möchten, fügen Sie Ihrem Projekt <declare-styleable>
-Ressourcen hinzu. Üblicherweise werden diese Ressourcen in einer
res/values/attrs.xml Datei platziert. Hier sehen Sie
ein Beispiel für eine attrs.xml-Datei:
<resources> <declare-styleable name="PieChart"> <attr name="showText" format="boolean" /> <attr name="labelPosition" format="enum"> <enum name="left" value="0"/> <enum name="right" value="1"/> </attr> </declare-styleable> </resources>
Dieser Code deklariert zwei benutzerdefinierte Attribute, showText und labelPosition, die zu einer formatierbaren Entität namens PieChart gehören. Der Name der formatierbaren Entität ist konventionsgemäß derselbe
Name wie der
Name der Klasse,
die die benutzerdefinierte Ansicht definiert. Es ist zwar nicht erforderlich, dieser Konvention zu folgen,
aber viele beliebte Code
editoren sind darauf angewiesen, um die Anweisungsergänzung zu ermöglichen.
Nachdem Sie benutzerdefinierte Attribute definiert haben, können Sie sie in XML-Layoutdateien genauso wie integrierte
Attribute verwenden. Der einzige
Unterschied besteht darin, dass Ihre benutzerdefinierten Attribute zu einem anderen Namespace gehören. Sie gehören nicht zum
Namespace http://schemas.android.com/apk/res/android, sondern zu http://schemas.android.com/apk/res/[your package name]. Hier sehen Sie ein Beispiel für die Verwendung der
definierten Attribute für
PieChart:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res-auto"> <com.example.customviews.charting.PieChart custom:showText="true" custom:labelPosition="left" /> </LinearLayout>
Damit die lange Namespace-URI nicht wiederholt werden muss, wird im Beispiel eine
xmlns Anweisung verwendet. Mit dieser Anweisung wird dem Namespace http://schemas.android.com/apk/res/com.example.customviews der Alias custom zugewiesen.
Sie können für Ihren Namespace einen beliebigen Alias auswählen.
Beachten Sie den Namen des XML-Tags, mit dem die benutzerdefinierte Ansicht dem Layout hinzugefügt wird. Es ist der vollständig
qualifizierte Name der
benutzerdefinierten Ansichtsklasse. Wenn Ihre Ansichtsklasse eine innere Klasse ist, qualifizieren Sie sie weiter
mit dem Namen der äußeren Klasse der Ansicht.
Die Klasse
PieChart hat beispielsweise eine innere Klasse namens PieView. Wenn Sie die
benutzerdefinierten Attribute aus dieser Klasse verwenden möchten, verwenden Sie das Tag com.example.customviews.charting.PieChart$PieView.
Benutzerdefinierte Attribute anwenden
Wenn eine Ansicht aus einem XML-Layout erstellt wird, werden alle Attribute im XML-Tag aus dem Ressourcenbundle gelesen und als AttributeSet an den Konstruktor der Ansicht übergeben.
Es ist zwar möglich, Werte direkt aus dem AttributeSet zu lesen, dies hat jedoch einige Nachteile:
- Ressourcenverweise in Attributwerten werden nicht aufgelöst.
- Stile werden nicht angewendet.
Übergeben Sie stattdessen das AttributeSet an
obtainStyledAttributes().
Diese Methode gibt ein
TypedArray
Array von
Werten zurück, die
bereits dereferenziert und formatiert sind.
Der Android-Ressourcencompiler erledigt viel Arbeit für Sie, um den Aufruf von
obtainStyledAttributes()
zu vereinfachen. Für jede <declare-styleable>
Ressource im Verzeichnis res/ definiert die generierte R.java sowohl ein Array von Attribut
IDs als auch eine Reihe von
Konstanten, die den Index für jedes Attribut im Array definieren. Mit den vordefinierten
Konstanten lesen
Sie die Attribute aus dem TypedArray. So liest
die PieChart Klasse
ihre Attribute:
Kotlin
init { context.theme.obtainStyledAttributes( attrs, R.styleable.PieChart, 0, 0).apply { try { mShowText = getBoolean(R.styleable.PieChart_showText, false) textPos = getInteger(R.styleable.PieChart_labelPosition, 0) } finally { recycle() } } }
Java
public PieChart(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.PieChart, 0, 0); try { mShowText = a.getBoolean(R.styleable.PieChart_showText, false); textPos = a.getInteger(R.styleable.PieChart_labelPosition, 0); } finally { a.recycle(); } }
Beachten Sie, dass TypedArray Objekte
eine freigegebene Ressource sind
und nach der Verwendung wieder freigegeben werden müssen.
Attribute und Ereignisse hinzufügen
Attribute sind eine leistungsstarke Möglichkeit, das Verhalten und Aussehen von Ansichten zu steuern. Sie können jedoch nur gelesen werden,
wenn die Ansicht initialisiert wird. Um dynamisches Verhalten zu ermöglichen, stellen Sie für jedes
benutzerdefinierte Attribut ein Getter- und
Setter-Paar für Attribute bereit. Das folgende Snippet zeigt, wie PieChart ein Attribut
namens showText bereitstellt:
Kotlin
fun isShowText(): Boolean { return mShowText } fun setShowText(showText: Boolean) { mShowText = showText invalidate() requestLayout() }
Java
public boolean isShowText() { return mShowText; } public void setShowText(boolean showText) { mShowText = showText; invalidate(); requestLayout(); }
Beachten Sie, dass setShowText invalidate()
aufruft und requestLayout(). Diese Aufrufe sind entscheidend
damit sich die Ansicht zuverlässig verhält. Sie müssen
die Ansicht nach jeder Änderung ihrer Attribute, die ihr
Aussehen verändern könnte, ungültig machen, damit das
System weiß, dass sie neu gezeichnet werden muss. Ebenso müssen Sie ein neues Layout anfordern, wenn
sich ein Attribut so ändert,
dass sich die Größe oder Form der Ansicht ändern könnte. Wenn Sie diese Methodenaufrufe vergessen, können
schwer zu findende
Fehler auftreten.
Benutzerdefinierte Ansichten müssen auch Ereignis-Listener unterstützen, um wichtige Ereignisse zu kommunizieren. Beispielsweise stellt ein benutzerdefiniertes Ereignis namens OnCurrentItemChanged bereit, um Listener zu benachrichtigen, dass der Nutzer das Kreisdiagramm gedreht hat, um sich auf ein neues Kreissegment zu konzentrieren.PieChart
Es ist leicht, Attribute und Ereignisse zu vergessen, insbesondere wenn Sie der einzige Nutzer der benutzerdefinierten Ansicht sind. Wenn Sie sich die Zeit nehmen, die Schnittstelle Ihrer Ansicht sorgfältig zu definieren, können Sie zukünftige Wartungskosten senken. Eine gute Regel ist, immer alle Attribute bereitzustellen, die sich auf das sichtbare Aussehen oder Verhalten Ihrer benutzerdefinierten Ansicht auswirken.
Barrierefreiheit bei der Websiteentwicklung berücksichtigen
Ihre benutzerdefinierte Ansicht muss eine breite Palette von Nutzern unterstützen. Dazu gehören Nutzer mit Behinderungen, die sie daran hindern, einen Touchscreen zu sehen oder zu verwenden. So unterstützen Sie Nutzer mit Behinderungen: Gehen Sie wie folgt vor:
- Beschriften Sie Ihre Eingabefelder mit dem
android:contentDescriptionAttribut. - Senden Sie Barrierefreiheitsereignisse, indem Sie
sendAccessibilityEvent()bei Bedarf aufrufen. - Unterstützen Sie alternative Controller wie ein Steuerkreuz oder einen Trackball.
Weitere Informationen zum Erstellen barrierefreier Ansichten finden Sie unter Apps barrierefreier machen.