Ansichtsklasse erstellen

Jetpack Compose ausprobieren
Jetpack Compose ist das empfohlene UI-Toolkit für Android. Informationen zum Arbeiten mit Layouts in Compose

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:contentDescription Attribut.
  • 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.