Android_Tutorial_Lektion35_fotolia_RA_Studio_46292813

Programmier Tutorial: Apps für Android entwickeln – Teil 35: Eine Custom Preference für unsere App bereitstellen

In dieser Lektion werden wir unserer Android App eine selbst gestaltete Einstellung, eine sog. Custom Preference, hinzufügen. Die Einstellung wird über einen eigenen Einstellungsdialog verfügen, mit dem der Einstellungswert ausgewählt werden kann. Durch die Custom Preference soll die Anzahl der vom Webserver angeforderten Zitate vorgegeben werden können.

Zum Vorgeben der Zitatanzahl werden wir ein NumberPicker-Widget nutzen, mit dessen Hilfe Zahlenwerte schnell und intuitiv eingestellt werden können. Wegen dem verwendeten Widget werden wir unsere Custom Preference als NumberPickerPreference bezeichnen.


Die Custom Preference werden wir zu Beginn dieser Lektion implementierten. Dazu werden wir die folgenden drei Arbeitsschritte ausführen:

  1. Definieren des Dialog-Layouts unserer Custom Preference
  2. Implementieren der Preference-Klasse unserer Custom Preference
  3. Implementieren der Dialog-Klasse unserer Custom Preference

Danach werden wir unsere Custom Preference, die NumberPickerPreference, dem Einstellungsbildschirm unserer Anwendung hinzufügen. Dazu werden wir ein NumberPickerPreference-Element in die XML-Datei preferences.xml einfügen.

Das neue Einstellungselement wird dann zur Laufzeit von dem SettingsFragment automatisch in eine App-Einstellung umgewandelt, jedoch wird es dann noch nicht möglich sein, den Einstellungsdialog per Klick zu öffnen. Mit einer Änderung an der SettingsFragment-Klasse werden wir auch dieses Problem beheben und mit Hilfe der onDisplayPreferenceDialog() Methode entsprechend auf Klicks reagieren.

Abschließend werden wir unsere Android App im Emulator auf einem Android Virtual Device ausführen und prüfen, ob unsere Custom Preference richtig in den Einstellungsbildschirm unserer Android App eingebunden ist und der Einstellungswert korrekt für die Datenanfrage verwendet wird.

1. Eine Custom Preference in Android implementieren

Die Preference-API von Android stellt eine Reihe an Standard-Einstellungen zur Verfügung, die für die meisten Aufgaben völlig ausreichend sind. So können bspw. SwitchPreference– und CheckBoxPreference-Elementen sehr gut für das Aktivieren/Deaktivieren von App-Funktionen oder das EditTextPreference für die Eingabe von Text genutzt werden.

In einigen Situationen sind die Standard-Einstellungen jedoch nicht ausreichend. Es ist bspw. keine Standard-Einstellung vorhanden, die es dem Benutzer ermöglicht eine Zahl mit Hilfe eines NumberPicker-Widgets auszuwählen.

Möchte man dem Nutzer eine solche Einstellungsmöglichkeit zur Verfügung stellen, muss dafür eine benutzerdefinierte App-Einstellung (Custom Preference) implementiert werden. Eine Custom Preference kann wie eine normale Standard-Einstellung in den Einstellungsbildschirm der eigenen Anwendung eingebunden werden.

Um eine solche Custom Preference zu implementieren, sind folgende Schritte erforderlich:

  1. Definieren des Dialog-Layouts unserer Custom Preference – Unsere selbst gestaltete Einstellung wird einen eigenen Einstellungsdialog besitzen. Für diesen muss im ersten Schritt ein Layout in einer XML-Layout Datei definiert werden. In dem Dialog-Layout werden die für die Einstellung benötigten UI-Elemente definiert. Dieses Layout werden wir später in der Preference-Klasse als Dialog Layout Resource verwenden und dadurch eine Verbindung zwischen App-Einstellung und Einstellungsdialog herstellen.

  2. Implementieren der Preference-Klasse unserer Custom Preference – Im zweiten Arbeitsschritt muss die eigentliche Einstellung, das Preference-Element selbst, implementiert werden. Das Preference-Element muss den eigenen Einstellungswert verwalten können und auf das Layout des Einstellungsdialogs verweisen. Es wird den Namen NumberPickerPreference tragen.

    Implementiert wird das Preference-Element mit Hilfe einer eigenen Klasse, die entweder von der Preference-Klasse selbst oder einer ihrer Tochterklassen abgeleitet werden muss. Da unser Preference-Element über einen eigenen Einstellungsdialog verfügen soll, leiten wir die zu erstellende Klasse von der DialogPreference-Klasse ab.

  3. Implementieren der Dialog-Klasse unserer Custom Preference – Im dritten Arbeitsschritt muss der Dialog der Einstellung implementiert werden. Über diesen Dialog kann der Einstellungswert, die Anzahl der angeforderten Zitate, ausgewählt werden. Der Einstellungsdialog wird von dem SettingsFragment geöffnet, sobald der Benutzer auf das Custom Preference-Element im Einstellungsbildschirm klickt.

    Implementiert wird der Einstellungsdialog mit Hilfe einer eigenen Klasse, die von der PreferenceDialogFragmentCompat-Klasse abgeleitet werden muss. Wie sich am Namen der Super-Klasse bereits erkennen lässt, handelt es sich eigentlich um ein Einstellungsdialog-Fragment anstatt um einen normalen Dialog. Zur besseren Verständlichkeit werden wir ihn aber weiterhin als Einstellungsdialog bezeichnen.

Die so implementierte Custom Preference kann nun wie eine Standard-Einstellung in die eigene Android App eingebunden werden. Dazu muss sie als Preference-Element in die XML-Ressourcen Datei preferences.xml innerhalb der PreferenceScreen-Wurzelelements eingefügt werden. Sie wird dann, wie das andere Preference-Element auch, von unserem SettingsFragment in eine App-Einstellung umgewandelt.

Die Custom Preference ist dann zwar schon in dem Einstellungsbildschirm unserer Anwendung aufgeführt, jedoch bleibt ein Klick auf das Einstellungselement zu diesem Zeitpunkt noch wirkungslos. Um dies zu ändern, muss die onDisplayPreferenceDialog() Methode der SettingsFragment-Klasse überschrieben werden. Sie ist für das Öffnen des Einstellungsdialogs der Custom Preference zuständig.

Mit dem Überschreiben der onDisplayPreferenceDialog() Methode ist das Implementieren der Custom Preference abgeschlossen. Sie ist in die Einstellungen der Anwendung eingebunden und ihr Einstellungsdialog rückt in den Vordergrund, sobald der Benutzer auf das Custom Preference-Element im Einstellungsbildschirm klickt.

Wir werden nun die eben beschriebenen Schritte in die Praxis umsetzen und eine eigene Custom Preference für unsere Android App implementieren. Mit Hilfe der erstellten Custom Preference soll die Anzahl der angeforderten Zitate vorgegeben werden können.

1.1 Definieren des Dialog-Layouts unserer Custom Preference

Wie bereits oben beschrieben, müssen drei Arbeitsschritte ausgeführt werden, um eine Custom Preference zu implementieren. Der erste Schritt besteht darin das Layout des Einstellungsdialogs der Custom Preference zu definieren, welcher angezeigt wird, sobald der Nutzer auf die Einstellung im Einstellungsbildschirm klickt.

Wir werden nun dieses Dialog-Layout definieren. Dazu werden wie eine XML-Layout Datei erstellen und in ihr die benötigten UI-Elemente definieren. Dieses Layout werden wir später in der Custom Preference-Klasse als Dialog Layout Resource verwenden und dadurch eine Verbindung von App-Einstellung und Einstellungsdialog herstellen.

Die zu erstellende XML-Layout Datei muss in dem res/layout/ Ressourcen-Ordner abgelegt werden. Dieses Verzeichnis existiert bereits, wir hatten es in einer vorherigen Lektion angelegt, und muss daher nicht mehr von uns erstellt werden.

Wir erstellen nun die XML-Layout Datei preference_dialog_numberpicker.xml, mit welcher wir das Aussehen des Einstellungsdialogs unserer Custom Preference definieren. Dazu führen wir die folgenden Schritte aus:

  1. Mit der rechten Maustaste auf den Ordner layout/ in dem Project Tool Window klicken.
  2. Anschließend den Eintrag New des Kontext-Menüs anklicken.
  3. Danach auf Layout resource file klicken.
custompreference_dialog_layout

Erstellen eines Layout Resource File für die preference_dialog_numberpicker.xml XML-Layout Datei

Anschließend öffnet sich der New Layout Resource File-Dialog, der uns bei der Erstellung der XML-Ressourcen Datei unterstützt. Wir müssen nun die beiden Felder des Dialogs ausfüllen.

In dem New Layout Resource File-Dialog nehmen wir die folgenden Einstellungen vor:

  1. Als Dateinamen tragen wir preference_dialog_numberpicker.xml in das Feld File name ein.
  2. Den Wert für das Root element (Wurzelelement des UI-Layouts) lassen wir auf LinearLayout stehen.
custompreference_dialog_layout_create

Dateinamen und das Wurzelelement für die neue XML-Layout Datei vorgeben

Anschließend bestätigen wir den New Layout Resource File-Dialog mit einem Klick auf den OK Button, woraufhin die neue XML-Ressourcen Datei automatisch von Android Studio erstellt und im Editorfenster der IDE geöffnet wird.

Falls die Datei nicht automatisch geöffnet wurde, führen wir das Öffnen manuell durch. Dazu klicken wir doppelt auf ihren Dateinamen preference_dialog_numberpicker.xml im Project Tool Window von Android Studio. Die Datei befindet sich im res/layout/ Ordner unseres Projekts.

Standardmäßig öffnet sich das Editorfenster in der Design-Ansicht. Damit der XML-Code der Layout Datei angezeigt wird, müssen wir unten im Editorfenster den Tab Text anklicken.

Den generierten XML-Code löschen wir vollständig und fügen an dessen Stelle den folgenden XML-Code ein:

preference_dialog_numberpicker.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_vertical|center_horizontal"
    android:orientation="horizontal">

    <NumberPicker
        android:id="@+id/number_picker"
        android:layout_width="100dp"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingStart="@dimen/row_padding"
        android:text="@string/preference_quotecount_dialog_unit"
        android:textSize="@dimen/default_font_size" />

</LinearLayout>

Mit dem oberen Quellcode definieren wir das UI-Layout für den Einstellungsdialog unserer Custom Preference. Die visuelle Struktur des Dialogs besteht aus einem LinearLayout-Element als Wurzelelement des Layouts. Das LinearLayout-Element nimmt in sich ein NumberPicker– und ein TextView-Element auf.

Für das NumberPicker-Element haben wir mit android:id=“@+id/number_picker“ eine ID anlegen lassen. Über diese ID können wir später zur Laufzeit auf das korrespondierende NumberPicker-Objekt zugreifen. Durch das @ Symbol weiß der XML-Parser, dass es sich um eine ID-Ressource handelt. Durch das + Symbol wird angegeben, dass die ID-Ressource in der R.java Datei neu angelegt werden muss.

Das LinearLayout ordnet seine inneren Elemente horizontal an und nimmt als Bildschirmplatz die gesamte zur Verfügung stehende Höhe und Breite ein. Ihre beiden inneren Elemente werden dabei mittig zentriert.

In Android Studio sollte die preference_dialog_numberpicker.xml Datei nun wie folgt aussehen:

custompreference_dialog_layout_code_2a

Die XML-Layout Datei preference_dialog_numberpicker.xml mit den vorgenommenen Änderungen

Nun haben wir das UI-Layout für den Einstellungsdialog unserer Custom Preference angelegt. Als Nächstes werden wir die Preference-Klasse erstellen, mit der die Eigenschaften und das Verhalten der Custom Preference definiert werden.

1.2 Implementieren der Preference-Klasse unserer Custom Preference

Im zweiten Arbeitsschritt muss die eigentliche Einstellung, das Preference-Element selbst, implementiert werden. Das Preference-Element muss den eigenen Einstellungswert verwalten können und auf das Layout des Einstellungsdialogs, welches wir bereits definiert haben, verweisen.

Implementiert wird das Preference-Element mit Hilfe einer eigenen Klasse, die entweder von der Preference-Klasse selbst oder einer ihrer Tochterklassen abgeleitet werden muss. Da unser Preference-Element über einen eigenen Einstellungsdialog verfügen soll, leiten wir die zu erstellende Klasse von der DialogPreference-Klasse ab.

Hinweis: Die Klasse DialogPreference ist direkt von der Preference-Klasse abgeleitet und kann als Basisklasse für Preference-Element, die Dialog-basierend sind, genutzt werden. Durch Klick auf solche Preferences wird ein Dialog geöffnet, der die eigentlichen Steuerelemente der Einstellung enthält.

Die neue Klasse wird den Namen NumberPickerPreference tragen und mit Hilfe des Create New Class-Dialog von Android Studio erstellt werden. Beim Anlegen der Klasse ist unbedingt darauf zu achten, dass sie in dem Package-Ordner unseres Projekts abgelegt wird.

Wir legen nun die neue Datei NumberPickerPreference.java folgendermaßen an:

  1. Mit der rechten Maustaste auf den Package-Ordner de.codeyourapp.zitate klicken.
  2. Anschließend den Eintrag New des Kontext-Menüs anklicken.
  3. Danach auf den Eintrag Java Class klicken.
custompreference_create_preference

Erstellen der NumberPickerPreference-Klasse in den Package-Ordner des Projekts

Anschließend öffnet sich der Create New Class-Dialog, der uns bei der Erstellung der neuen Java Klasse unterstützt. Wir müssen nur einige Felder des Dialogs ausfüllen.

In dem Create New Class-Dialog nehmen wir nun die folgenden Einstellungen vor:

  1. Als Klassennamen tragen wir in das Feld Name NumberPickerPreference ein.
  2. Den Wert für Kind lassen wir auf Class stehen.
  3. Die Felder Superclass und Interface(s) lassen wir leer.
  4. Als Package sollte bereits automatisch unser Package-Ordner de.codeyourapp.zitate eingetragen sein.
  5. Alle anderen Einstellungen übernehmen wir unverändert.
  6. Den Dialog bestätigen wir mit einem Klick auf den OK Button.
custompreference_create_preference_dialog

Den Namen für die NumberPickerPreference-Klasse vorgeben

Android Studio legt nun automatisch die neue Java Klasse an. Dabei wird auch der minimale Quellcode für das Klassengerüst erzeugt. Diesen benötigen wir aber nicht und werden ihn daher vollständig durch unseren eigenen Code ersetzen.

Dazu öffnen wir die Klassendatei NumberPickerPreference.java im Editorfenster von Android Studio mit einem Doppelklick auf den entsprechenden Eintrag in der linken Project-Ansicht.

Anschließend ersetzen wir ihren gesamten Quelltext mit folgendem Code:

NumberPickerPreference.java

package de.codeyourapp.zitate;

import android.content.Context;
import android.content.res.TypedArray;
import androidx.preference.DialogPreference;
import android.util.AttributeSet;

public class NumberPickerPreference extends DialogPreference {

    public static final int DEFAULT_VALUE = 10;
    private int mPickedNumber;

    public NumberPickerPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        setDialogLayoutResource(R.layout.preference_dialog_numberpicker);

        setDialogTitle(R.string.preference_quotecount_dialog_title);
        setPositiveButtonText(R.string.preference_quotecount_dialog_positive_button_text);
        setNegativeButtonText(R.string.preference_quotecount_dialog_negative_button_text);
    }

    public int getValue() {
        return mPickedNumber;
    }

    public void setValue(int newPickedNumber) {
        mPickedNumber = newPickedNumber;

        // Speichern des Einstellungswerts in die SharedPreferences und Anpassen der Summary.
        persistInt(mPickedNumber);
        setSummary(mPickedNumber + " " + getContext().getString(R.string.preference_quotecount_summary));
    }

    @Override
    protected Object onGetDefaultValue(TypedArray a, int index) {
        // Auslesen des Standardwerts anhand des XML-Attributs.
        // Falls dies nicht möglich ist, wird die Konstante DEFAULT_VALUE verwendet.
        return a.getInt(index, DEFAULT_VALUE);
    }

    @Override
    protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
        // Setzen des Einstellungswerts auf den in den SharedPreferences gespeicherten Wert
        // oder Verwenden des Standardwerts.
        if (restorePersistedValue) {
            setValue(getPersistedInt(mPickedNumber));
        } else {
            setValue((int) defaultValue);
        }
        setSummary(mPickedNumber + " " + getContext().getString(R.string.preference_quotecount_summary));
    }

}

In Zeile 1 definieren wir zu welchem Package die NumberPickerPreference-Klasse gehört. An dieser Stelle muss der Package-Name verwendet werden, der auch in dem Project-View angezeigt wird.

In den Zeilen 3 bis 6 werden die drei Klassen Context, TypedArray und DialogPreference, sowie das Interface AttributeSet per Import-Anweisung sichtbar gemacht. Hier muss unbedingt darauf geachtet werden, die Klasse androidx.preference.DialogPreference aus der AndroidX Preference Library zu importieren und nicht die Klasse des Android Frameworks.

Anschließend wird mit den Zeilen 8 bis 53 die NumberPickerPreference-Klasse definiert. Sie wird von der DialogPreference-Klasse abgeleitet, wodurch sie die Fähigkeit einen Einstellungsdialog darzustellen erbt. Das Aussehen dieses Dialogs müssen wir selbst mit Hilfe einer XML-Layout Datei vorgeben. Ebenso müssen wir die Logik implementieren, durch die der Einstellungswert verwaltet wird.

Die NumberPickerPreference-Klasse besitzt die Konstante DEFAULT_VALUE und die Membervariablen mPickedNumber, in welcher der Einstellungswert gespeichert wird.

In den Zeilen 13 bis 20 wird der Konstruktor definiert. Er besitzt zwei Parameter, einen vom Typ Context und einen vom Typ AttributeSet. Seine Hauptaufgabe besteht darin, diese beiden Parameter an den Konstruktor der Super-Klasse DialogPreference weiterzugeben und den Einstellungsdialog zu initialisieren. Von ihm wird mit Hilfe der setDialogLayoutResource() Methode das Layout für den Einstellungsdialog vorgegeben. Der Methode wird dazu die Ressourcen-ID des im vorherigen Schritt erstellten Dialog-Layouts übergeben. Zudem wird der Dialog-Titel und der jeweilige Button-Text vorgegeben.

Als Nächstes wird in den Zeilen 22 bis 24 die Methode getValue() definiert, welche für das Auslesen des Einstellungswerts verantwortlich ist. Wir werden sie später vom Einstellungsdialog aus nutzen, um den Wert des NumberPicker-Elements einzustellen.

In den Zeilen 26 bis 32 wird die setValue() Methode definiert, welche für das Speichern des Einstellungswerts zuständig ist. Ihr wird der im NumberPicker-Element eingestellte Wert als Argument übergeben. Sie speichert den erhaltenen Wert dann persistent mit Hilfe der persistInt() Methode in die SharedPreferences ab. Zudem passt sie den Zusammenfassungstext der Einstellung mit Hilfe der setSummary() Methode an den erhaltenen Wert an. Wir werden sie später vom Einstellungsdialog aus nutzen, um den mit dem NumberPicker-Element eingestellten Wert zu speichern.

Weiterhin werden die beiden Methoden onGetDefaultValue() und onSetInitialValue() der Super-Klasse überschrieben, die sie von der Preference-Klasse erbt. Die Methoden sind für das Initialisieren der Einstellung verantwortlich.

Mit der onGetDefaultValue() Methode in den Zeilen 35 bis 39 wird der Standardwert der Einstellung ausgelesen. Sie wird aufgerufen, wenn ein Preference-Element in eine Einstellung umgewandelt wird und deren Standardwert ausgelesen werden muss.

Mit der onSetInitialValue() Methode in den Zeilen 42 bis 51 wird der initiale Einstellungswert gesetzt. Dabei wird der Wert aus den SharedPreferences ausgelesen, falls der Parameter restorePersistedValue true ist. Falls nicht, wird der Standardwert als initialer Einstellungswert verwendet. Zudem wird der Zusammenfassungstext der Einstellung an den gesetzten Wert angepasst.

In Android Studio sollte die NumberPickerPreference.java Klassendatei wie folgt aussehen:

custompreference_preference_code

Die Klassendatei NumberPickerPreference.java mit dem eingefügten Quellcode

In der oberen Abbildung ist die NumberPickerPreference.java Klassendatei dargestellt. Es muss unbedingt darauf geachtet werden, dass sich die neue Klasse in dem Package-Ordner de.codeyourapp.zitate befindet. Zur Kontrolle kann auf den oberen Projektstruktur-Reiter geklickt werden, um die aktuelle Struktur unseres Android Projekts anzuzeigen.

Wir haben nun das UI-Layout des Einstellungsdialogs und die Preference-Klasse unserer Custom Preference angelegt. Um die Implementierung unserer Custom Preference abzuschließen, fehlt jetzt nur noch die Dialog-Klasse, welche den Einstellungsdialog implementiert.

1.3 Implementieren der Dialog-Klasse unserer Custom Preference

Im dritten Arbeitsschritt muss der Dialog der Einstellung implementiert werden. Über diesen Dialog kann der Einstellungswert, die Anzahl der angeforderten Zitate, ausgewählt werden. Der Einstellungsdialog wird von dem SettingsFragment geöffnet, sobald der Benutzer auf das Custom Preference-Element im Einstellungsbildschirm klickt.

Implementiert wird der Einstellungsdialog mit Hilfe einer eigenen Klasse, die von der PreferenceDialogFragmentCompat-Klasse abgeleitet werden muss. Wie sich am Namen der Super-Klasse bereits erkennen lässt, handelt es sich eigentlich um ein Einstellungsdialog-Fragment anstatt um einen normalen Dialog. Zur besseren Verständlichkeit werden wir ihn aber weiterhin als Einstellungsdialog bezeichnen.

Die neue Klasse wird den Namen NumberPickerPreferenceDialogFragment tragen und mit Hilfe des Create New Class-Dialog von Android Studio erstellt werden. Beim Anlegen der Klasse ist unbedingt darauf zu achten, dass sie in dem Package-Ordner unseres Projekts abgelegt wird.

Wir legen nun die neue Datei NumberPickerPreferenceDialogFragment.java folgendermaßen an:

  1. Mit der rechten Maustaste auf den Package-Ordner de.codeyourapp.zitate klicken.
  2. Anschließend den Eintrag New des Kontext-Menüs anklicken.
  3. Danach auf den Eintrag Java Class klicken.
custompreference_create_dialogpref

Erstellen der NumberPickerPreferenceDialogFragment-Klasse in den Package-Ordner des Projekts

Anschließend öffnet sich der Create New Class-Dialog, der uns bei der Erstellung der neuen Java Klasse unterstützt. Wir müssen nur einige Felder des Dialogs ausfüllen.

In dem Create New Class-Dialog nehmen wir nun die folgenden Einstellungen vor:

  1. Als Klassennamen tragen wir in das Feld Name NumberPickerPreferenceDialogFragment ein.
  2. Den Wert für Kind lassen wir auf Class stehen.
  3. Die Felder Superclass und Interface(s) lassen wir leer.
  4. Als Package sollte bereits automatisch unser Package-Ordner de.codeyourapp.zitate eingetragen sein.
  5. Alle anderen Einstellungen übernehmen wir unverändert.
  6. Den Dialog bestätigen wir mit einem Klick auf den OK Button.
custompreference_create_dialog_dialog

Den Namen für die NumberPickerPreferenceDialogFragment-Klasse vorgeben

Android Studio legt nun automatisch die neue Java Klasse an. Dabei wird auch der minimale Quellcode für das Klassengerüst erzeugt. Diesen benötigen wir aber nicht und werden ihn daher vollständig durch unseren eigenen Code ersetzen.

Dazu öffnen wir die Klassendatei NumberPickerPreferenceDialogFragment.java im Editorfenster von Android Studio mit einem Doppelklick auf den entsprechenden Eintrag in der linken Project-Ansicht.

Anschließend ersetzen wir ihren gesamten Quelltext mit folgendem Code:

An dieser Stelle endet der freie Inhalt dieser Lektion. Wir hoffen, sie hat dir bis hierher gefallen! Du kannst sie im geschützten Bereich von ProgrammierenLernenHQ fortsetzen, in welchem sich alle Lektionen unserer Android Online-Kurse befinden.

Unsere Android Kurse bestehen aus insgesamt 43 großen Lektionen und sind unterteilt in 13 frei zugängliche und 30 Premium-Lektionen. Die Premium-Lektionen befinden sich in dem geschützten Bereich und sind nur für Käufer unseres Android Online-Kurs Gesamtpaket zugänglich.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813 An dieser Stelle endet der freie Inhalt dieser Lektion. Wir hoffen, sie hat dir bis hierher gefallen! Du kannst sie durch Kauf unseres Android Online-Kurs Gesamtpakets freischalten.

In unserem Android Online-Kurs Gesamtpaket befinden sich 43 große Lektionen, in denen wir dir schrittweise zeigen, wie voll funktionstüchtige Android Apps programmiert werden.

Diese Lektion ist Teil unseres Android Gesamtpakets. Insgesamt sind unsere Online-Kurse unterteilt in 13 frei zugängliche und 30 Premium-Lektionen.

Die Premium-Lektionen befinden sich in dem geschützten Bereich und sind nur für Käufer des Android Online-Kurs Gesamtpakets zugänglich.



Welche Inhalte befinden sich im Android Online-Kurs Gesamtpaket?

  • Das Gesamtpaket enthält alle Android Online-Kurse von ProgrammierenLernenHQ.
  • Im Paket enthalten ist unser großer Android Apps Programmieren Online-Kurs. Er ist unser Hauptkurs und besteht aus 35 großen Lektionen. Die Grundlagen der Android App Entwicklung praxisnah und verständlich zu lehren, ist das Hauptziel des Android Apps Programmieren Kurses.
  • Im Paket enthalten ist auch unser SQLite Datenbank App Programmieren Online-Kurs. Dieser Spezialkurs besteht aus 8 großen Lektionen und ist als weiterführender Kurs konzipiert worden. Der Kurs schließt an unseren Android Apps Programmieren Hauptkurs an und widmet sich dem speziellen Thema der SQLite Datenbanken.
  • Durch den Kauf erhältst du unbegrenzten Zugang zu allen Inhalten unseres Android Online-Kurs Gesamtpakets. Wir werden in Zukunft weitere Lektionen hinzufügen. Auch auf alle zukünftigen Lektionen erhältst du vollen Zugriff.

Wir hoffen, Dich bald als neuen Kursteilnehmer unserer Android Online-Kurse begrüßen zu dürfen!

Einmal kaufen und dadurch zeitlich unbegrenzten Zugriff auf alle Inhalte unseres Android Online-Kurs Gesamtpakets erhalten.



Hinweis: Der untere Quellcode ist Teil des geschützten Bereichs von ProgrammierenLernenHQ. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte.
Erfahre mehr über unsere Android Online-Kurse.

android_programmieren_lernen_blurry_sourcecode

Der obere Quellcode ist Teil des geschützten Bereichs. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte. Klicke auf die Info-Box, um mehr zu erfahren.

In Zeile 1 definieren wir zu welchem Package die NumberPickerPreferenceDialogFragment-Klasse gehört. An dieser Stelle muss der Package-Name verwendet werden, der auch in dem Project-View angezeigt wird.

In den Zeilen 3 bis 6 werden die vier Klassen Bundle, PreferenceDialogFragmentCompat, View und NumberPicker per Import-Anweisung sichtbar gemacht.

Anschließend wird mit den Zeilen 8 bis 49 die NumberPickerPreferenceDialogFragment-Klasse definiert. Sie wird von der PreferenceDialogFragmentCompat-Klasse abgeleitet, wodurch sie die Eigenschaften eines Fragments und zusätzliche Kompatibilitätsmechanismen erbt.

Die neue Klasse besitzt die Membervariablen mNumberPicker vom Datentyp NumberPicker, in welcher eine Referenz auf das NumberPicker-Widget des Einstellungsdialogs gespeichert wird. Die Referenz wird benötigt, um den Wert der NumberPicker-Instanz auszulesen und zu setzen.

Für die NumberPickerPreferenceDialogFragment-Klasse wird kein spezieller Konstruktor benötigt, stattdessen muss die statische Methode newInstance() definiert werden, mit der sich Instanzen der Klasse erzeugen lassen. Diese Methode wird in den Zeilen 12 bis 19 definiert. Sie besitzt einen Parameter vom Typ String mit dessen Hilfe ihr der Schlüssel der zugrunde liegenden Preference übergeben wird. Durch ihn weiß der Einstellungsdialog welcher Einstellung er zugewiesen wurde.

In der newInstance() Methode wird zunächst eine NumberPickerPreferenceDialogFragment-Instanz erzeugt und dieser anschließend mit Hilfe eines Bundle-Objekt der Preference-Schlüssel zugewiesen. Die erzeugte Instanz wird schließlich per return-Anweisung an den Aufrufer zurückgegeben. Wir werden später von der SettingsFragment-Klasse aus die statische newInstance() Methode aufrufen und auf diese Weise den Einstellungsdialog erzeugen lassen.

Bevor der Einstellungsdialog angezeigt wird, müssen die visuellen Elemente initialisiert werden. Dies geschieht in der Methode onBindDialogView(), die wir in den Zeilen 22 bis 34 überschreiben. Am Anfang des Methodenrumpfs wird ihre Implementation der Super-Klasse aufgerufen. Anschließend wird das NumberPicker-Objekt des Dialogs mit Hilfe der findViewById() Methode und der entsprechenden Ressourcen-ID, die wir im Dialog-Layout definiert haben, angefordert.

Für das NumberPicker-Objekt werden dessen Minimal- und Maximalwert vorgegeben. Weiterhin wird mit Zeile 28 festgelegt, dass der NumberPicker nicht endlos gedreht werden kann, sondern mit dem Anfangswert beginnt und dem Endwert endet. Zudem wird mit Zeile 29 bestimmt, dass das NumberPicker-Widget den Fokus nicht erhält. Dadurch wird verhindert, dass auf manchen Android Geräten die virtuelle Tastatur aufklappt.

Schließlich wird mit den Zeilen 32 und 33 der Wert des NumberPicker-Objekts auf den aktuellen Einstellungswert gesetzt. Dazu wird mit getPreference() die dem Dialog zugrunde liegende Einstellung, die NumberPickerPreference über die der Dialog geöffnet wurde, angefordert und deren Wert als aktuellen Wert für das NumberPicker-Objekt gesetzt.

Als letzte Methode wird in den Zeilen 37 bis 47 die onDialogClosed() Methode überschrieben. Sie ist in der Super-Klasse als abstract deklariert und muss daher zwingend von uns implementiert werden. Sie wird automatisch vom Android System aufgerufen, sobald der Einstellungsdialog vom Benutzer geschlossen wird. In der Methode prüfen wir, ob der OK-Button (positive result) geklickt wurde und speichern dann den aktuellen Wert des NumberPicker-Objekts als neuen Einstellungswert.

Dazu lesen wir zuerst den aktuellen Wert des NumberPicker-Objekts aus, fordern danach die zugehörige Einstellung, das NumberPickerPreference-Objekt, an und setzen den Einstellungswert auf den ausgelesenen Wert des NumberPicker-Objekts. Dies geschieht mit Hilfe der setValue() Methode, die den Einstellungswert persistent in die SharedPreferences speichert.

In Android Studio sollte die NumberPickerPreferenceDialogFragment.java Klassendatei wie folgt aussehen:

android_programmieren_lernen_blurry_sourcecode

Der obere Quellcode ist Teil des geschützten Bereichs. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte. Klicke auf die Info-Box, um mehr zu erfahren.

In der oberen Abbildung ist die NumberPickerPreferenceDialogFragment.java Klassendatei dargestellt. Es muss unbedingt darauf geachtet werden, dass sich die neue Klasse in dem Package-Ordner de.codeyourapp.zitate befindet.

Wir haben nun den Einstellungsdialog, das Dialog-Layout und die Preference-Klasse unserer Custom Preference angelegt. Die Implementierung der Custom Preference ist somit abgeschlossen. Wir können sie nun unserem Einstellungsbildschirm als normales Preference-Element hinzufügen.

2. Einfügen der Custom Preference in die preferences.xml Datei

Wir werden nun die implementierte Custom Preference unseren App-Einstellungen hinzufügen. Dabei können wir das Wissen aus der vorherigen Lektion nutzen, da die Custom Preference wie ein normales Preference-Element in die App-Einstellungen eingebunden wird.

Wir öffnen nun die XML-Datei preferences.xml im Editorfenster von Android Studio. Dazu klicken wir doppelt auf ihren Dateinamen im Project Tool Window. Die Datei befindet sich im res/xml/ Ordner unseres Projekts. Falls das Editorfenster in der Design-Ansicht geöffnet wurde, muss der untere Tab mit der Bezeichnung Text angeklickt werden, um den XML-Code bearbeiten zu können.

Dem bereits vorhandenen Code der preferences.xml Datei fügen wir die markierten Zeilen hinzu:

preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android">

    <PreferenceCategory android:title="@string/preference_category_title">

        <SwitchPreferenceCompat
            android:key="@string/preference_xmlmode_key"
            android:title="@string/preference_xmlmode_title"
            android:summary="@string/preference_xmlmode_summary_off"
            android:defaultValue="false" />

        <de.codeyourapp.zitate.NumberPickerPreference
            android:key="@string/preference_quotecount_key"
            android:title="@string/preference_quotecount_title"
            android:defaultValue="10" />

    </PreferenceCategory>
</androidx.preference.PreferenceScreen>

Mit den Zeilen 13 bis 16 fügen wir unsere Custom Preference in den Einstellungsbildschirm unserer Anwendung ein. Der Einstellungsbildschirm (Preference Screen) enthält nun zwei Preference-Elemente, ein <SwitchPreferenceCompat> und ein <NumberPickerPreference> Element.

Beim Einfügen unseres <NumberPickerPreference> Elements muss der vollqualifizierende Name der implementierenden Klasse verwendet werden. Da das Element von unserer NumberPickerPreference-Klasse implementiert wird, ergibt sich dieser aus dem Package-Namen gefolgt von dem Klassennamen zu de.codeyourapp.zitate.NumberPickerPreference.

Für das <NumberPickerPreference> Element haben wir die folgenden drei Attribute definiert:

  • android:key – Mit diesem Attribut wird der Einstellungsschlüssel zugewiesen. Dieser Schlüssel wird vom Android System verwendet, um den Wert der Einstellung in die SharedPreferences zu speichern. Nur durch Angabe eines Schlüssels kann der vom Benutzer eingestellten Wert persistent gespeichert werden.

  • android:title – Mit diesem Attribut wird der Titel vorgegeben. Der Titel der NumberPickerPreference lautet „Anzahl angeforderte Zitate“ und wird mit Hilfe der in der vorherigen Lektion angelegten String-Ressource vorgegeben.

  • android:defaultValue – Jede Einstellung sollte über einen Standardwert verfügen, der vom Android System als Anfangswert in die SharedPreferences geschrieben wird. Wir haben den Standardwert des NumberPickerPreference-Elements auf die Zahl 10 gesetzt.

In Android Studio sollte die preferences.xml Datei nun wie folgt aussehen:

custompreference_preferences_xml

Die XML-Datei preferences.xml mit dem eingefügten Quellcode

Wir haben nun unsere Custom Preference (Markierung A) als Preference-Element in die preferences.xml XML-Datei eingefügt. Sie ist damit unseren Einstellungsbildschirm hinzugefügt worden. Von Android wird sie wie ein normales Preference-Element behandelt und daher auch automatisch vom SettingsFragment mit Hilfe der addPreferencesFromResource() Methode in eine App-Einstellung umgewandelt.

Es ist daher möglich unsere Custom Preference bereits jetzt zu testen. Dabei muss aber beachtet werden, dass sie noch nicht voll funktionstüchtig ist. Als Einstellung im Einstellungsbildschirm wird sie zwar schon angezeigt, jedoch führt ein Klick auf sie momentan noch zum Absturz unserer Anwendung. Dies müssen wir unbedingt berücksichtigen, wenn wir unsere Custom Preference im nächsten Abschnitt testen.

2.1 Testen der Custom Preference auf einem AVD im Emulator

Wir werden nun unserer Android App auf einem Android Virtual Device im Emulator ausführen lassen. Auf diese Weise können wir direkt überprüfen, wie unsere Custom Preference in den Einstellungsbildschirm eingebunden wurde. Aber Vorsicht! Ein Klick auf die Einstellung wird unsere App abstürzen lassen.

Unsere App starten wir dazu wie gewohnt über den Run > Run 'app' Menüeintrag, den wir über die obere Menüleiste erreichen.

In den unteren Abbildungen ist unsere Android App auf dem virtuellen Gerät zu sehen. Die beiden Activities, MainActivity und DetailActivity, besitzen in dem Overflow Menu ihrer App Bar einen Einstellungen-Eintrag. Auf diesen Eintrag klicken wir nun jeweils einmal:

screenshot_settings_1aa

Klick auf Einstellungen in der MainActivity

screenshot_settings_2aa

Klick auf Einstellungen in der DetailActivity


screenshot_custompreference

Nach Anklicken des Einstellungen-Menüeintrags wird jeweils die SettingsActivity gestartet, welche nun auch die Custom Preference als App-Einstellung enthält

In der großen Abbildung ist die SettingsActivity dargestellt. Sie enthält das SettingsFragment, welches nun zwei App-Einstellungen verwaltet, die SwitchPreference oben und unsere selbst-implementierte NumberPickerPreference direkt darunter.

Achtung! Unsere Custom Preference, die NumberPickerPreference, wird zwar schon vom SettingsFragment verwaltet und ihr Einstellungswert persistent in den SharedPreferences gespeichert, jedoch führt ein Klick auf die Einstellung momentan noch zum Absturz unserer Anwendung.

Die Ursache des Absturzes liegt darin, dass das SettingsFragment versucht den Einstellungsdialog der Custom Preference zu öffnen, ihr jedoch noch nicht mitgeteilt wurde, welcher Dialog zur Custom Preference gehört. Da sie somit den zugehörigen Einstellungsdialog nicht öffnen kann, wirft das SettingsFragment eine entsprechende Ausnahmen.

Im nächsten Abschnitt werden wir die Absturzursache beseitigen und die notwendige Änderung an der SettingsFragment-Klasse vornehmen, so dass sie den von uns implementierten Einstellungsdialog der Custom Preference öffnet, sobald die NumberPickerPreference-Einstellung angeklickt wird.

3. Öffnen des Einstellungsdialogs der Custom Preference

Für das Öffnen des Einstellungsdialogs unserer Custom Preference ist die SettingsFragment-Klasse zuständig. Sie verwendet dazu die onDisplayPreferenceDialog() Methode, welche sie von ihrer Super-Klasse PreferenceFragmentCompat erbt. Diese Callback-Methode wird vom Android System automatisch aufgerufen, sobald ein Klick auf ein Einstellungselement detektiert wurde.

Um den Einstellungsdialogs unserer Custom Preference aufrufen zu lassen, müssen wir daher die Methode onDisplayPreferenceDialog() der SettingsFragment-Klasse so überschreiben, dass von ihr eine Instanz der NumberPickerPreferenceDialogFragment-Klasse erzeugt und als Einstellungsdialog angezeigt wird.

Wir öffnen nun die Klassendatei SettingsFragment.java im Editor von Android Studio mit einem Doppelklick auf ihren Dateinamen im Project Tool Window. Die Klassendatei befindet sich im Package-Ordner de.codeyourapp.zitate unseres Projekts.

In der SettingsFragment.java nehmen wir folgende Änderungen vor:

android_programmieren_lernen_blurry_sourcecode

Der obere Quellcode ist Teil des geschützten Bereichs. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte. Klicke auf die Info-Box, um mehr zu erfahren.

Im oberen Quellcode der SettingsFragment-Klasse wurden in Zeilen 3 die Klasse DialogFragment per Import-Anweisung innerhalb der Klasse sichtbar gemacht. Sie wird für das Anzeigen des Einstellungsdialogs unserer Custom Preference benötigt.

In den Zeilen 51 bis 64 wird die onDisplayPreferenceDialog() definiert. Sie besitzt einen Parameter vom Typ Preference, der das Preference-Objekt aufnimmt, welches vom Benutzer angeklickt wurde. Die Aufgabe der onDisplayPreferenceDialog() Methode ist das Öffnen des zum angeklickten Preference-Objekt gehörenden Einstellungsdialogs.

Für Standard-Einstellungen, wie bspw. einer EditTextPreference, erfüllt die Methoden-Implementierung der Super-Klasse diese Aufgabe bereits und kann den zugehörigen Einstellungsdialog selbständig öffnen. Für Custom Preferences kann sie dies nicht, da sie den Einstellungstyp und somit den zugehörigen Einstellungsdialog nicht kennt.

Wir müssen also den neuen Einstellungstyp, unsere Custom Preference, der onDisplayPreferenceDialog() Methode bekannt geben und sie so erweitern, dass sie den zugehörigen Einstellungsdialog, das NumberPickerPreferenceDialogFragment-Objekt, anzeigen kann.

Mit dem if-Zweig in den Zeilen 53 bis 60 wird der neue Einstellungstyp, die NumberPickerPreference, bekannt gegeben und geprüft, ob das angeklickte Einstellungsobjekt von diesem Typ ist. Ist dies der Fall, wird eine neue Instanz der NumberPickerPreferenceDialogFragment-Klasse mit Hilfe der newInstance() Methode erzeugt. Ihr wird dabei der Schlüssel des zugehörigen Preference-Objekts übergeben, wodurch eine Verknüpfung zwischen Einstellungsdialog und Einstellung erfolgt.

Das erzeugte DialogFragment ist der Einstellungsdialog unserer Custom Preference. Es muss nun nur noch mit Hilfe des FragmentManagers angezeigt werden. Dazu wird mit der Methode setTargetFragment(), dem neuen DialogFragment das startende Fragment bekannt gegeben, zu welchem nach Beenden des Dialogs wieder zurückgekehrt wird. Anschließend wird mit der Methode show(), eine FragmentTransaction ausführt, bei der SettingsFragment durch das NumberPickerPreferenceDialogFragment ausgetauscht wird, wodurch der Einstellungsdialog in den Vordergrund rückt.

Der else-Zweig in den Zeilen 60 bis 63 wird nur betreten, falls es sich bei dem angeklickten Einstellungsobjekt nicht um ein NumberPickerPreferenceDialogFragment-Objekt handelt. In einem solchen Fall wird die Methoden-Implementierung der Super-Klasse aufgerufen, die das Öffnen der Einstellungsdialoge der Standard-Einstellungstypen übernimmt.

In Android Studio sollte die SettingsFragment.java Klassendatei nun wie folgt aussehen:

android_programmieren_lernen_blurry_sourcecode

Der obere Quellcode ist Teil des geschützten Bereichs. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte. Klicke auf die Info-Box, um mehr zu erfahren.

In der oberen Abbildung ist die überarbeitete SettingsFragment.java Klassendatei dargestellt. Die hinzugefügten Codezeilen sind mit Markierungen versehen worden. Welche Bedeutung die jeweilige Zeile bzw. der jeweilige Code-Block besitzt, ist in der unteren Liste angegeben:

  1. B – Die benötigten Import-Anweisungen zum Sichtbarmachen der DialogFragment-Klasse.
  2. C – In der onDisplayPreferenceDialog() Methode wird überprüft, ob unser Custom Preference-Element angeklickt wurde und, falls dem so ist, der zugehörige Einstellungsdialog geöffnet.

Wir haben nun alle erforderlichen Änderungen an der SettingsFragment-Klasse durchgeführt. Mit Hilfe der überschriebenen Methode onDisplayPreferenceDialog() kann nun der Einstellungsdialog unserer Custom Preference geöffnet werden. Unsere Android App stürzt nun nicht mehr ab, falls der Einstellungseintrag der Custom Preference im Einstellungsbildschirm angeklickt wird.

Die neue App-Einstellung ist nun voll funktionstüchtig, jedoch wird ihr Einstellungswert momentan noch nicht von unserer Anwendung ausgewertet bzw. für die Anfrage an den Webserver genutzt. Dies werden wir als Nächstes ändern und den Wert der NumberPickerPreference für den Bau des Anfrage-Strings verwenden.

4. Auf den Einstellungswert in der MainActivity-Klasse reagieren

Mit unserer Custom Preference, der NumberPickerPreference, soll die Anzahl der angeforderten Zitate vorgegeben werden. Wie viele Zitate vom Webserver angefordert werden, wird durch den Anfrage-String des HTTP-Requests festgelegt.

Der Anfrage-String muss also in Abhängigkeit vom aktuellen Einstellungswert der NumberPickerPreference gebildet werden. Der Zusammenbau dieses Strings wird von der refreshListView() Methode der MainActivity-Klasse aus gesteuert. Daher müssen wir an genau dieser Stelle den aktuellen Wert der NumberPickerPreference-Einstellung auslesen und entsprechend darauf reagieren.

Wir werden nun die notwendige Änderung an der refreshListView() Methode durchführen. Dazu öffnen wir die Klassendatei MainActivity.java im Editor von Android Studio mit einem Doppelklick auf ihren Dateinamen im Project Tool Window. Die Klassendatei befindet sich im Package-Ordner de.codeyourapp.zitate unseres Projekts.

In die MainActivity.java fügen wir folgenden markierten Zeilen in die refreshListView() Methode ein:

MainActivity.java

private void refreshListView() {
    int quoteCount = 8;
    int parsingMethod = Utility.JSON_PARSING_METHOD;

    // Auslesen der ausgewählten Einstellung aus den SharedPreferences
    SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
    String prefXmlModeKey = getString(R.string.preference_xmlmode_key);
    boolean isXmlModeOn = sharedPrefs.getBoolean(prefXmlModeKey, false);
    if (isXmlModeOn) parsingMethod = Utility.XML_PARSING_METHOD;

    // Auslesen des Einstellungswerts der Custom Preference aus den SharedPreferences
    String prefQuoteCountKey = getString(R.string.preference_quotecount_key);
    int defaultQuoteCount = NumberPickerPreference.DEFAULT_VALUE;
    quoteCount = sharedPrefs.getInt(prefQuoteCountKey, defaultQuoteCount);

    // Instanziieren des AsyncTask-Objekts und Starten des asynchronen Tasks
    RequestQuotesTask requestQuotesTask = new RequestQuotesTask();
    requestQuotesTask.execute(quoteCount, parsingMethod);
}

In der refreshListView() Methode wurden nur die Zeilen 12 bis 14 eingefügt. Es ist wichtig, die neuen Zeilen exakt an der markierten Stelle einzufügen, da für das Auslesen des Einstellungswerts auf das SharedPreferences-Objekt sharedPrefs zugegriffen wird.

In Zeile 12 wird der Schlüssel der NumberPickerPreference aus der String-Ressource R.string.preference_quotecount_key ausgelesen. Der Schlüssel ist erforderlich, um Einstellungswert aus den SharedPreferences auslesen zu können.

In Zeile 13 wird die Variabel defaultQuoteCount deklariert und auf den Standardwert der NumberPickerPreference gesetzt. Dies geschieht mit Hilfe der Konstante DEFAULT_VALUE die wir in der NumberPickerPreference-Klasse für diese Zwecke angelegt haben.

In Zeile 14 wird der aktuelle Wert der Custom Preference mit Hilfe der getInt() Methode ausgelesen. Ihr werden dazu der Einstellungsschlüssel der NumberPickerPreference und der Standard-Einstellungswert übergeben. Der Standardwert wird nur benötigt, falls kein zum Schlüssel passender Wert aus den SharedPreferences ausgelesen werden konnte.

In Zeile 18 wird dann der asynchrone Task, mit dessen Hilfe die Zitatdaten beim Webserver angefordert werden, gestartet. Dies erfolgt durch Aufruf der execute() Methode, der die beiden Variablen quoteCount und parsingMethod als Argumente übergeben werden. Über die Variable quoteCount wird nun die Anzahl der angeforderten Zitate, in Abhängigkeit von dem Wert der NumberPickerPreference, vorgegeben.

Zur besseren Kontrolle ist der gesamte Quellcode der MainActivity.java Datei hier noch einmal aufgeführt worden. Es wurden nur die Zeilen 276 bis 278 der refreshListView() Methode hinzugefügt.

Zum Betrachten des gesamten Quellcodes muss der untere Block aufgeklappt werden:

android_programmieren_lernen_blurry_sourcecode

Der obere Quellcode ist Teil des geschützten Bereichs. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte. Klicke auf die Info-Box, um mehr zu erfahren.

Durch das Überarbeiten der refreshListView() Methode werden ab jetzt die aktuellen Werte der SwitchPreference– und NumberPickerPreference-Einstellung für den Bau des Anfrage-Strings genutzt. Von unserer App wird somit auf die vom Benutzer getätigten Einstellungen reagiert und in Abhängigkeit davon das XML- bzw. JSON-Format verwendet und die Anzahl der angeforderten Zitate angepasst.

In Android Studio sollte der Inhalt der MainActivity.java Klassendatei nun wie folgt aussehen:

android_programmieren_lernen_blurry_sourcecode

Der obere Quellcode ist Teil des geschützten Bereichs. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte. Klicke auf die Info-Box, um mehr zu erfahren.

In der oberen Abbildung ist die MainActivity.java Klassendatei dargestellt. Es wurden nur drei Zeilen in die refreshListView() Methode eingefügt. Sie ist daher als einzige Methode aufgeklappt. Die eingefügten Codezeilen sind von einem blauen Rahmen umschlossen (Markierungen D).

5. Ausführen und Testen unserer Android App

Wir werden nun unserer Android App auf einem Android Virtual Device im Emulator ausführen lassen und überprüfen, ob unsere Anwendung den Einstellungsdialog unserer Custom Preference öffnet und den Einstellungswert für die Serveranfrage nutzt.

Unsere App starten wir dazu wie gewohnt über den Run > Run 'app' Menüeintrag, den wir über die obere Menüleiste erreichen.

In den unteren Abbildungen ist unsere Android App auf dem virtuellen Gerät zu sehen. Die beiden Activities, MainActivity und DetailActivity, besitzen in dem Overflow Menu ihrer App Bar einen Einstellungen-Eintrag. Auf diesen Eintrag klicken wir nun jeweils einmal:

screenshot_settings_1aa

Klick auf Einstellungen in der MainActivity

screenshot_settings_2aa

Klick auf Einstellungen in der DetailActivity


screenshot_custompreference

Nach Anklicken des Einstellungen-Menüeintrags wird jeweils die SettingsActivity gestartet, welche nun auch die Custom Preference als App-Einstellung enthält

In der großen Abbildung ist die SettingsActivity dargestellt. Sie enthält das SettingsFragment, welches nun zwei App-Einstellungen verwaltet, die SwitchPreference oben und unsere selbst-implementierte NumberPickerPreference direkt darunter.

Die SettingsFragment-Klasse ist nun in der Lage mit Hilfe der onDisplayPreferenceDialog() Methode den Einstellungsdialog unserer Custom Preference zu öffnen. Um dies zu testen, klicken wir nun auf die NumberPickerPreference. Sie befindet sich an der zweiten Stelle im Einstellungsbildschirm.

Sobald die NumberPickerPreference angeklickt wurde, öffnet sich der Einstellungsdialog:

screenshot_custompreference

Nach Anklicken der NumberPickerPreference öffnet sich der Einstellungsdialog unserer Custom Preference

Wir stellen in den Einstellungsdialog unserer Custom Preference den Wert 7 mit Hilfe des NumberPicker-Widgets ein. Anschließend klicken wir auf den OK Button, um den Dialog wieder zu schließen und den eingestellten Wert übernehmen zu lassen.

Der Einstellungswert wird jetzt automatisch in die SharedPreferences unter dem Schlüssel der NumberPickerPreference abgelegt. Wir können dies auch direkt anhand des Zusammenfassungstexts der Custom Preference prüfen, der nun den aktuellen Wert der Einstellung dem Benutzer mitteilt.

Wie in der unteren Abbildung zu erkennen ist, wurde der eingestellte Wert übernommen. Pro Anfrage werden nun 7 Zitate vom Webserver angefordert:

screenshot_custompreference

Der neue Wert unserer Custom Preference wurde übernommen und wird in der Summary mitgeteilt

Als Nächstes möchten wir noch prüfen, ob der Einstellungswert der Custom Preference auch für den Bau des Anfrage-Strings verwendet wird. Dies lässt sich am besten mit Hilfe des Logging-Werkzeugs Logcat in Android Studio kontrollieren.

Wir überprüfen nun im Logcat Tool Window von Android Studio den Anfrage-String des HTTP-Request mit folgenden Schritten:

  1. Wir öffnen das Logcat Tool Window mit einem Klick auf den Logcat-Tab am unteren Bildschirmrand.
  2. In der Drop-Down Liste stellen wir die Prioritätsstufe auf Verbose ein.
  3. In das Suchfeld geben wir Utility|RequestQuotesTask (ohne Leerzeichen) als Suchbegriff ein.
  4. Für die hintere Drop-Down Liste wählen wir den Eintrag Show only selected application aus.
  5. In unserer Android App führen wir die Swipe-Refresh Geste durch und fordern damit neue Zitate vom Webserver an.
custompreference_log_quotecount

Der Anfrage-String des HTTP-Requests enthält den aktuellen Einstellungswert (count=7) der Custom Preference

In der oberen Abbildung ist die Logcat-Ausgabe unserer Android App zu sehen. In der Anwendung wurde der Einstellungswert der NumberPickerPreference auf den Wert 7 gestellt und anschließend neue Zitatdaten vom Webserver per Swipe-Refresh angefordert.

Wie am Anfrage-String zu erkennen ist, werden 7 Zitate im XML-Format vom Webserver angefordert. Der Anfrage-String besitzt den Parameter count mit dem Wert 7, welcher die Zitatanzahl vorgibt, und den Parameter mode mit dem Wert 1, wodurch die Zitatdaten im XML-Format angefordert werden.

Zusammenfassung

In dieser Lektion haben wir unserer Android App eine selbst gestaltete Einstellung, eine sog. Custom Preference, hinzugefügt. Die neue Einstellung besitzt einen eigenen Einstellungsdialog, mit dem der Einstellungswert ausgewählt werden kann. Als Wert wird die Anzahl der vom Webserver angeforderten Zitate von der Custom Preference vorgegeben.

Zum Einstellen der Zitatanzahl haben wir ein NumberPicker-Widget genutzt, mit dessen Hilfe Zahlenwerte schnell und intuitiv eingestellt werden können. Wegen dem verwendeten Widget haben wir unsere Custom Preference als NumberPickerPreference bezeichnet.

Die Custom Preference wurde mit den folgenden drei Arbeitsschritten implementiert:

  1. Definieren des Dialog-Layouts unserer Custom Preference
  2. Implementieren der Preference-Klasse unserer Custom Preference
  3. Implementieren der Dialog-Klasse unserer Custom Preference

Die implementierte Custom Preference, die NumberPickerPreference, haben wir anschließend dem Einstellungsbildschirm unserer Anwendung hinzugefügt und dazu ein NumberPickerPreference-Element in die preferences.xml XML-Ressourcen Datei eingefügt.

Damit der Einstellungsdialog der eingefügten Einstellung per Klick geöffnet werden kann, mussten wir danach eine Änderung an der SettingsFragment-Klasse vornehmen und die onDisplayPreferenceDialog() Methode implementieren, die für das Öffnen der Einstellungsdialog verantwortlich ist. Zudem haben wir mit einer kleinen Änderung an der MainActivity-Klasse auf den Einstellungswert der NumberPickerPreference reagiert, um diesen für den Anfrage-String des HTTP-Requests zu verwenden.

Abschließend haben wir unsere Android App im Emulator auf einem Android Virtual Device ausgeführt und überprüft, ob unsere Custom Preference richtig in den Einstellungsbildschirm unserer Android App eingebunden ist und der Einstellungswert korrekt für die Datenanfrage verwendet wird.

Weiterführende Literatur




Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.