Ansichtsklasse erstellen

Schreiben Sie jetzt
Jetpack Compose ist das empfohlene UI-Toolkit für Android. Hier erfahren Sie, wie Sie in „Compose“ mit Layouts arbeiten.

Eine gut durchdachte benutzerdefinierte Ansicht ist wie jede andere gut gestaltete Klasse. Es kapselt einen bestimmten Satz von Funktionen mit einer einfachen Schnittstelle, nutzt CPU und Speicher effizient und so weiter. Neben einer gut durchdachten Klasse muss eine benutzerdefinierte Ansicht auch Folgendes bieten:

  • Es muss den Android-Standards entsprechen.
  • Geben Sie benutzerdefinierte, anpassbare Attribute an, die mit Android-XML-Layouts funktionieren.
  • Bedienungshilfen-Ereignisse senden.
  • Sie muss 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 all diese Anforderungen erfüllt. In dieser Lektion wird erläutert, wie Sie mit dem Android-Framework die Hauptfunktionen einer Ansichtsklasse erstellen.

Weitere Informationen finden Sie unter Komponenten der benutzerdefinierten Ansicht.

Abgeleitete Klassen einer Ansicht erstellen

Alle im Android-Framework definierten Ansichtsklassen erweitern View. Sie können View auch direkt mit Ihrer benutzerdefinierten Ansicht erweitern oder Zeit sparen, indem Sie eine der vorhandenen abgeleiteten Klassen wie Button erweitern.

Damit Android Studio mit Ihrer Ansicht interagieren kann, müssen Sie mindestens einen Konstruktor bereitstellen, der ein Context- und ein AttributeSet-Objekt als Parameter verwendet. Mit diesem Konstruktor kann der Layout-Editor 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 ihre Darstellung und ihr Verhalten mit Elementattributen. Sie können benutzerdefinierte Ansichten auch mithilfe von XML hinzufügen und gestalten. So aktivieren Sie dieses Verhalten in Ihrer benutzerdefinierten Ansicht:

  • Definieren Sie in einem <declare-styleable> -Ressourcenelement benutzerdefinierte Attribute für Ihre Ansicht.
  • Geben Sie Werte für die Attribute in Ihrem XML-Layout an.
  • Attributwerte zur Laufzeit abrufen
  • Wenden Sie die abgerufenen Attributwerte auf Ihre Ansicht an.

In diesem Abschnitt wird erläutert, wie Sie benutzerdefinierte Attribute definieren und ihre Werte angeben. Im nächsten Abschnitt geht es um das Abrufen und Anwenden der Werte zur Laufzeit.

Fügen Sie Ihrem Projekt <declare-styleable> -Ressourcen hinzu, um benutzerdefinierte Attribute zu definieren. Es ist üblich, diese Ressourcen in einer res/values/attrs.xml-Datei zu speichern. Hier 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>

Mit diesem Code werden die beiden benutzerdefinierten Attribute showText und labelPosition deklariert, die zu einer anpassbaren Entität namens PieChart gehören. Der Name der formatierbaren Entität entspricht standardmäßig dem Namen der Klasse, die die benutzerdefinierte Ansicht definiert. Obwohl es nicht notwendig ist, diese Konvention zu befolgen, sind viele gängige Codeeditoren auf diese Namenskonvention angewiesen, um die Anweisung zu vervollständigen.

Nachdem du benutzerdefinierte Attribute definiert hast, kannst du sie wie integrierte Attribute in Layout-XML-Dateien 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]. So werden beispielsweise die für PieChart definierten Attribute verwendet:

<?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 der lange Namespace-URI nicht wiederholt werden muss, wird im Beispiel eine xmlns-Anweisung verwendet. Durch diese Anweisung wird dem Namespace http://schemas.android.com/apk/res/com.example.customviews der Alias custom zugewiesen. Sie können einen beliebigen Alias für den Namespace auswählen.

Beachten Sie den Namen des XML-Tags, mit dem die benutzerdefinierte Ansicht zum Layout hinzugefügt wird. Es ist der voll qualifizierte Name der benutzerdefinierten Ansichtsklasse. Wenn Ihre View-Klasse 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. Zur Verwendung der benutzerdefinierten Attribute aus dieser Klasse nutzen 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 Ressourcen-Bundle gelesen und als AttributeSet an den Konstruktor der Ansicht übergeben. Werte können zwar direkt aus AttributeSet gelesen werden, dies hat jedoch einige Nachteile:

  • Ressourcenverweise innerhalb von Attributwerten werden nicht aufgelöst.
  • Stile werden nicht angewendet.

Übergeben Sie stattdessen AttributeSet an obtainStyledAttributes(). Diese Methode gibt ein TypedArray-Array von Werten zurück, die bereits dereferenziert und formatiert sind.

Der Android-Ressourcen-Compiler erledigt eine Menge Arbeit für dich, um das Aufrufen von obtainStyledAttributes() zu vereinfachen. Für jede <declare-styleable>-Ressource im Verzeichnis res/ definiert die generierte R.java sowohl ein Array mit Attribut-IDs als auch einen Satz von Konstanten, die den Index für jedes Attribut im Array definieren. Sie verwenden die vordefinierten Konstanten, um die Attribute aus der TypedArray zu lesen. So liest die Klasse PieChart 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();
   }
}

TypedArray-Objekte sind freigegebene Ressourcen und müssen nach der Verwendung recycelt werden.

Attribute und Ereignisse hinzufügen

Mit Attributen können Sie das Verhalten und die Darstellung von Ansichten auf leistungsstarke Weise steuern. Sie können jedoch nur gelesen werden, wenn die Ansicht initialisiert wird. Für ein dynamisches Verhalten stellen Sie für jedes benutzerdefinierte Attribut ein Property-Getter-Setter-Paar bereit. Das folgende Snippet zeigt, wie PieChart eine Eigenschaft namens showText freigibt:

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();
}

setShowText ruft invalidate() und requestLayout() auf. Diese Aufrufe sind entscheidend, um sicherzustellen, dass sich die Ansicht zuverlässig verhält. Sie müssen die Ansicht nach jeder Änderung an ihren Eigenschaften, durch die sich ihre Darstellung ä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 eine Eigenschaft so ändert, dass sich dies auf die Größe oder Form der Ansicht auswirken kann. Das Vergessen dieser Methodenaufrufe kann zu schwer zu findenden Fehlern führen.

Benutzerdefinierte Ansichten müssen außerdem Ereignis-Listener unterstützen, damit wichtige Ereignisse kommunizieren können. Beispielsweise aktiviert PieChart ein benutzerdefiniertes Ereignis namens OnCurrentItemChanged, um Listener darüber zu informieren, dass der Nutzer das Kreisdiagramm gedreht hat, um den Fokus auf ein neues Kreissegment zu legen.

Es kann leicht vergessen, Eigenschaften und Ereignisse verfügbar zu machen, insbesondere wenn Sie der einzige Nutzer der benutzerdefinierten Ansicht sind. Wenn Sie sich die Zeit nehmen, die Oberfläche Ihrer Ansicht sorgfältig zu definieren, können Sie zukünftige Wartungskosten senken. Es empfiehlt sich, immer alle Eigenschaften verfügbar zu machen, die sich auf die sichtbare Darstellung oder das Verhalten Ihrer benutzerdefinierten Ansicht auswirken.

Barrierefreies Design

Ihre benutzerdefinierte Ansicht muss eine große Bandbreite von Nutzern unterstützen. Dazu gehören auch Nutzer mit Behinderungen, die verhindern, dass sie einen Touchscreen sehen oder verwenden. So unterstützen Sie Nutzer mit Beeinträchtigungen:

  • Verwende das Attribut android:contentDescription, um deine Eingabefelder mit Labels zu versehen.
  • Sende Ereignisse für Bedienungshilfen, indem du gegebenenfalls sendAccessibilityEvent() aufrufst.
  • Sie können alternative Controller wie ein Steuerkreuz oder einen Trackball unterstützen.

Weitere Informationen zum Erstellen barrierefreier Ansichten finden Sie unter Apps barrierefrei gestalten.