Android_Tutorial_Lektion33_fotolia_RA_Studio_46292813

Programmier Tutorial: Apps für Android entwickeln – Teil 33: Eine SettingsActivity für unsere App implementieren

In dieser Lektion werden wir eine SettingsActivity unserer Android App hinzufügen. Die neue Activity wird für das Darstellen unserer App-Einstellungen verantwortlich sein.

Für das Erstellen der SettingsActivity werden wir die Preference-API von Android nutzen, die das Implementieren einheitlicher App-Einstellungen ermöglicht.

Auf diese Weise kann die Benutzererfahrung stark verbessert werden. Die Nutzer können die Einstellungselemente leichter wiedererkennen und somit intuitiver nutzen.


Wie die Preference-API für das Bereitstellen von App-Einstellungen verwendet werden sollte und was bzgl. älterer Android Versionen unbedingt beachtet werden muss, werden wir im theoretische Teil dieser Lektion und der beiden folgenden ausführlich behandeln.

Anschließend werden wir im praktischen Teil dieser Lektion die SettingsActivity und das SettingsFragment, welches von der Activity aufgenommen wird und für das Erzeugen und Verwalten der Einstellungen verantwortlich ist, erstellen. Bevor wir aber damit beginnen können, müssen noch einige Vorbereitungen getroffen werden, die notwendig sind, um das SettingsFragment ausführen zu können.

Die erstellte SettingsActivity werden wir anschließend in dem App Manifest unseres Android Projekts bekanntgeben, damit sie per expliziten Intent gestartet werden kann. Danach nehmen wir kleine Änderungen an der MainActivity und DetailActivity vor, so dass die neue SettingsActivity über deren Overflow Menu gestartet werden kann.

Abschließend werden wir unsere Android App im Emulator auf einem Android Virtual Device ausführen und prüfen, ob die SettingsActivity über das Overflow Menu der App Bar gestartet werden kann und ob das SettingsFragment korrekt in die Activity eingebunden ist.

1. Einstellungen in eine Android App integrieren

In Android werden mit Hilfe von Settings App-Einstellungen zur Verfügung gestellt. Die Settings sind für das Verhalten der Android App verantwortlich und ermöglichen dem Benutzer Anpassungen an der Anwendung vorzunehmen. Um den Nutzern eine bestimmte Einstellungsmöglichkeit bereitzustellen, stellt die Android Plattform sog. Preferences-Elemente zur Verfügung.

Einige Apps erlauben es dem Anwender bspw. zu entscheiden, ob Benachrichtigungen angezeigt werden oder wie oft Daten mit der Cloud synchronisiert werden sollen. Solche Einstellungen werden meist in einem Settings-Bildschirm (SettingsActivity) vorgenommen und anschließend als User-Preference (Benutzer-Vorlieben) abgespeichert.

Da jede zur Verfügung gestellte Einstellungsmöglichkeit durch ein Preference-Element definiert wird, ergeben sich aus der Summe aller Preference-Elemente die Einstellungen (Settings) einer Android App.

1.1 Einstellungen mit Hilfe von Preference-Elementen bereitstellen

Wie wir bereits erfahren haben, bestehen in Android die Einstellungen (Settings) einer App aus einer Ansammlung von Preference-Elementen. Die verschiedenen Preference-Elemente sind alle von der Preference-Hauptklasse abgeleitet und werden mit Hilfe der Preference-API in die eigene App eingebunden.

Das Einbinden der Preference-Elemente wird mit Hilfe einer XML-Datei vorgenommen. Diese Datei trägt meist den Namen preferences.xml und enthält die Einstellungsmöglichkeiten der App in Form verschiedener Unterklassen der Preference-Klasse.

Dabei ist jedes Preference-Element ein Block für eine einzelne Einstellung. Die verschiedenen Einstellungen können blockweise in einer Liste aufgereiht werden. Dabei besitzt jeder Block seine eigenen Merkmale und sein eigenes User Interface, durch das der Benutzer die gewünschte Einstellung vornehmen kann.

Eine ListPreference bspw. erzeugt ein Element, das bei Anklicken einen Dialog mit Listenelementen öffnet. Eine CheckBoxPreference erzeugt ein Element, das eine Checkbox anzeigt.

Jede Preference, die der Liste (den Settings) zugefügt wird, besitzt ein Schlüssel-Wert Paar (key-value pair), welches das Android System nutzt, um die vorgenommene Einstellung zu speichern. Die Einstellung wird zusammen mit den anderen App-Einstellungen in einer Default SharedPreferences-Datei gespeichert.

Wenn der Nutzer eine Einstellung ändert, aktualisiert das System den zum angegebenen Schlüssel passenden Wert in der SharedPreferences-Datei entsprechend. Da dieser Vorgang automatisch abläuft, sollte auf die SharedPreferences-Datei nur lesend zugegriffen werden.

In die SharedPreferences-Datei können aber keine beliebigen Werte abgespeicherten werden, sondern nur Werte der folgenden Datentypen:

  • Boolean
  • Float
  • Int
  • Long
  • String
  • String Set

Zudem muss beachtet werden, dass zu jedem Preference-Element genau ein Wert in der SharedPreferences-Datei per Schlüssel-Wert Paar abgelegt werden kann.

1.2 Erzeugen und Verwalten der Preference-Elemente

Da die Benutzeroberfläche der App-Einstellungen mit Hilfe der eben beschriebenen Preference-Elementen gebildet und nicht wie üblich aus View-Objekte zusammengesetzt wird, muss eine spezialisierte Activity– oder Fragment-Klasse für das Darstellen der Settings verwendet werden.

In der Vergangenheit (vor Android 9.0) wurden die Preference-Elemente mit Hilfe der Klassen PreferenceActivity bzw. PreferenceFragment den App-Einstellungen hinzugefügt und auf dem Bildschirm dargestellt. Welche der beiden Klassen dabei zu verwenden war, richtete sich nach der Android Zielplattform auf der die App ausgeführt werden sollte.

Als mögliche Herangehensweise wurde früher Folgendes empfohlen:

  • Android älter als 3.0 – Wenn die eigene App auf Android Geräten mit API Level 10 und niedriger ausführbar sein sollte, musste zum Erzeugen und Verwalten der Preferences die Klasse PreferenceActivity verwendet werden. Dies war erforderlich, da Fragmente erst mit API Level 11 eingeführt wurden.

  • Ab Android 3.0 – Wird die App ausschließlich auf Android Geräten mit API Level 11 und höher ausgeführt, sollte anstelle der PreferenceActivity-Klasse eine normale Activity-Klasse verwendet werden. Die Activity nimmt dann in sich ein PreferenceFragment auf, welches für das Erzeugen und Verwalten der Preferences verantwortlich ist. Auf diese Weise wird eine größere Flexibilität der Anwendung ermöglicht.

Seit Android 9.0 wird aber eine andere Herangehensweise empfohlen. Ab API Level 28 sollen die Preference-Elemente nur noch mit Hilfe der PreferenceFragmentCompat-Klasse erzeugt und verwaltet werden. Sie ist Teil der AndroidX Preference Library, wodurch eine Abwärtskompatibilität bis Android API Level 14 (Android 4.0) sichergestellt werden kann.

Eine PreferenceFragmentCompat-Instanz kann aber nicht alleine existieren, sondern muss von einer AppCompatActivity aufgenommen werden. Die Activity ist aber nur für das Einbinden des Fragments verantwortlich. Das Erzeugen und Verwalten der Preference-Elemente wird vollständig von der PreferenceFragmentCompat-Klasse übernommen, welche die Einstellungen der Anwendung aus den in der preferences.xml Datei definierten Preference-Blöcken erzeugt.

1.3 So integrieren wir die Einstellungen in unsere Android App

Um Einstellungen in unsere Anwendung zu integrieren, werden wir die neue Herangehensweise verwenden. Dazu werden wir in den nächsten drei Lektionen die folgenden Schritte durchführen:

  1. Implementieren der SettingsActivity – Zuerst werden wir die SettingsActivity-Klasse, die von der AppCompatActivity-Klasse abgeleitet ist, erstellen. Danach erstellen wir die SettingsFragment-Klasse, die von der PreferenceFragmentCompat-Klasse abgeleitet ist und das Verwalten der Preference-Elemente übernimmt. Anschließend fügen wir das SettingsFragment in die SettingsActivity ein.

    Dies wird alles in dieser Lektion erfolgen. Am Ende werden wir ein Rahmenwerk, bestehend aus einer SettingsActivity und einem SettingsFragment, implementiert haben, durch das Einstellungen für unsere Anwendungen bereitgestellt werden können.

  2. Bereitstellen der Einstellungen – Sobald das Rahmenwerk für das Bereitstellen von Einstellungen von uns erstellt wurde, können die ersten eigenen Einstellungen unserer App hinzugefügt werden. Dazu definieren wir zwei Einstellung mit Hilfe von Preference-Elementen in der preferences.xml Datei, welche wir vorher erzeugen müssen. Die Preference-Elemente lassen wir anschließend mit Hilfe der SettingsFragment-Klasse unserer App als Einstellung hinzufügen und von ihr verwalten.

    Dies wird in den nächsten beiden Lektionen erfolgen. Zunächst am Beispiel einer einfachen Standard-Einstellung und danach mit einer komplexeren, selbst gestalteten Einstellung (Custom Preference).

2. Unsere App auf die Preference-API vorbereiten

Wir werden nun mit dem Integrieren von Einstellungen in unsere eigene Android App beginnen. Da wir für das Erzeugen und Verwalten der Preference-Elemente die Klasse PreferenceFragmentCompat verwenden werden, müssen wir unser Android Studio Projekt darauf vorbereiten.

Um die PreferenceFragmentCompat-Klasse in unserem Projekt nutzen zu können sind zwei Vorbereitungsmaßnahmen erforderlich:

  1. Die benötigten AndroidX Libraries einbinden – In der build.gradle Datei des app-Moduls unseres Android Studio Projekts müssen die AndroidX Preference und Legacy-Preference Libraries korrekt eingebunden sein. Sie werden benötigt, um die PreferenceFragmentCompat-Klasse und das Material-Theme in unserer App verwenden zu können.

  2. Das Theme für das SettingsFragment definieren – In der styles.xml Ressourcen-Datei muss ein Theme für das SettingsFragment vorgegeben werden, damit dieses die Benutzeroberfläche der App-Einstellungen mit Hilfe der Preference-Elemente korrekt erzeugen kann.

2.1 Die benötigten AndroidX Libraries in die Gradle-Datei einbinden

Wir werden für das Bereitstellen unserer App-Einstellungen die PreferenceFragmentCompat-Klasse verwenden. So wird es aktuell auch von Android Developer empfohlen. Leider ist die Klasse aber nicht Teil des Android Frameworks, sondern ist der AndroidX Preference Library zugeordnet.

Um die PreferenceFragmentCompat-Klasse nutzen zu können, müssen wir daher die AndroidX Preference Library in unser Android Studio Projekt einbinden. Genauer gesagt, muss die Bibliothek für das app-Modul unseres Projekts zur Verfügung gestellt werden. Außerdem muss auch die AndroidX Legacy-Preference Library eingebunden werden, sie enthält ein Theme, welches für das Verwenden der PreferenceFragmentCompat-Klasse erforderlich ist.

Das Einbinden der beiden AndroidX Libraries geschieht mit Hilfe von Gradle-Dateien, die von Android Studio für den Erstellungsprozess der App verwendet werden. In einem Android Studio Projekt gibt es oft mehrere Gradle-Dateien, eine Hauptdatei und je eine Datei pro Modul. Da unser Projekt nur aus einem Anwendungsmodul, dem app-Modul, besteht, existieren genau zwei Gradle-Dateien.

Die Hauptdatei befindet sich im Wurzelverzeichnis unseres Android Studio Projekts. Sie ist die oberste build.gradle Datei. Sie gibt die Build-Anweisungen für das gesamte Projekt vor. Ist aber an dieser Stelle nur von geringer Bedeutung.

Viel wichtiger ist hingegen die Gradle-Datei auf Modulebene. Sie befindet sich im app/ Ordner unseres Projekts und ist für den Build-Prozess des app-Moduls verantwortlich. Wir müssen daher in ihr die beiden AndroidX Libraries für unsere App einbinden.

Dazu öffnen wir die build.gradle Datei des app/ Ordners im Editorfenster von Android Studio, indem wir doppelt auf ihren Dateinamen im Project Tool Window klicken:

support_libraries_appcompat_2b

In der Gradle-Datei des app-Moduls ist bereits die AndroidX Appcompat Library standardmäßig eingebunden

In der oberen Abbildung ist die build.gradle Datei des app-Moduls unseres Android Studio Projekts dargestellt. Sie ist bereits im Editorfenster von Android Studio geöffnet (app-Tab) und enthält noch den zu Projektstart generierten Inhalt.

Wie man anhand der Abbildung erkennen kann, ist eine AndroidX Library, die AndroidX Appcompat Library (Markierung 1), bereits in der Gradle-Datei des app-Moduls eingebunden. Sie wurde automatisch von Android Studio bei der Erstellung des Projekts eingebunden und wird aus Kompatibilitätsgründen standardmäßig benötigt. Sie enthält bspw. die Klasse AppCompatActivity, von der wir alle unsere eigenen Activities abgeleitet haben.

Um weitere AndroidX Libraries in das eigene Android Studio Projekt einzubinden, müssen diese in dem dependencies-Block der Gradle-Datei mit Hilfe des Schlüsselwortes implementation bekanntgeben werden.

Dabei muss die betreffende Bibliothek exakt bezeichnet werden. Die genaue Bezeichnung der von uns benötigten AndroidX Libraries kann man auf dem Google’s Maven Repository nachschlagen, in welchem sehr viele externe Bibliotheken von Google aufgeführt sind. Diese Bibliotheken sind nicht Teil des Android Frameworks, werden aber oft für spezielle Aufgaben, wie das Bereitstellen von Einstellungen, benötigt.

Wir werden nun mit folgenden Anweisungen die zwei benötigten AndroidX Preference Libraries in der Gradle-Datei einbinden. Dies geschieht im dependencies-Block direkt nach der in der oberen Abbildung markierten Anweisung (Markierung 1):

implementation 'androidx.preference:preference:1.0.0'
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'

In der unteren Abbildung sind die beiden benötigten AndroidX Preference Libraries bereits eingebunden:

support_libraries_preference_sync_2b

Die beiden markierten AndroidX Preference Libraries müssen exakt wie abgebildet in der Gradle-Datei des app-Moduls eingebunden sein

In der oberen Abbildung ist zu erkennen, dass die beiden AndroidX Preference Libraries bereits eingebunden sind (Markierung 2). Sie wurden direkt nach der AndroidX Appcompat Library eingebunden.

Um den Prozess abzuschließen und die beiden AndroidX Preference Libraries lokal unserem Android Studio Projekt hinzuzufügen, muss noch eine Synchronisation des Projekts durchgeführt werden. Dazu klicken wir auf den Sync Now-Link am rechten oberen Rand des Editorfensters (Markierung 3). Anschließend führt Android Studio die Synchronisation durch, in deren Folge die beiden AndroidX Preference Libraries von Google’s Maven Repository heruntergeladen werden.

Nur wenn die beiden Bibliotheken AndroidX Preference Library und AndroidX Legacy-Preference Library wie in der oberen Abbildung zu sehen (Markierung 2) eingebunden sind, können wir zum nächsten Schritt übergehen.

Insgesamt müssen diese drei AndroidX Libraries in der Gradle-Datei des app-Moduls eingebunden sein:

implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.preference:preference:1.0.0'
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'

Die AndroidX Appcompat Library haben wir bereits zu Projektbeginn benötigt, um die Klasse AppCompatActivity nutzen zu können. Die beiden AndroidX Preference Libraries benötigen wir erst ab dieser Lektion.

Sehr detailliert und hilfreiche Informationen über die AndroidX Libraries sind unter Support Library Packages auf der Android Developer Webseite angegeben. Es ist sehr empfehlenswert, sich die dort angegebenen Erklärung in Ruhe durchzulesen.

2.2 Das Theme für das SettingsFragment in styles.xml definieren

Da wir nun sichergestellt haben, dass die benötigten AndroidX Libraries korrekt in unser Android Studio Projekt eingebunden sind, können wir die zweite Vorbereitungsmaßnahme durchführen. Diese besteht darin ein Theme für das SettingsFragment zu definieren, mit dessen Hilfe die Benutzeroberfläche der App-Einstellungen erzeugt werden kann.

Dazu öffnen wir die XML-Datei styles.xml im Editorfenster von Android Studio, indem wir doppelt auf ihren Dateinamen im Project Tool Window klicken und definieren in ihr das Theme für das SettingsFragment. Die Datei befindet sich im res/values/ Ordner unseres Projekts.

Dem XML-Code der styles.xml Datei fügen wir nun die markierte Zeile hinzu:

styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>

        <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>

    </style>

</resources>

In den oberen XML-Code wurde nur Zeile 10 hinzugefügt, in welcher das Theme für das SettingsFragment definiert wird. Als preferenceTheme soll das PreferenceThemeOverlay.v14.Material verwendet werden. Das SettingsFragment wird später die Benutzeroberfläche der App-Einstellungen nach den Vorgaben dieses Themes erzeugen.

Auf das Theme referenzieren wir mit @style/PreferenceThemeOverlay.v14.Material:

  • Durch das @ Symbol weiß der XML-Parser, dass es sich um eine ID-Ressource handelt.

  • Mit style wird angegeben, das die ID zu einer Style-Ressource führt.

  • Der Ressourcename ist PreferenceThemeOverlay.v14.Material, über welchen auf das Theme zugegriffen werden kann. Dieses Theme wird nicht standardmäßig vom Android System als Theme-Vorlage bereitgestellt, sondern muss aus der AndroidX Legacy-Preference Library bezogen werden.

    Daher musste auch im vorherigen Schritt die Legacy-Preference-Bibliothek in unser Projekt mit Hilfe der Gradle-Datei eingebunden werden.

In Android Studio sollte die styles.xml Ressourcen-Datei nun wie folgt aussehen:

preference_theme_definieren_2a

In der styles.xml Datei wurde als Theme für das SettingsFragment PreferenceThemeOverlay.v14.Material vorgegeben

Durch die vorgenommene Änderung an der styles.xml Datei wurde das preferenceTheme für das SettingsFragment vorgegeben. Nach den Vorgaben des PreferenceThemeOverlay.v14.MaterialThemes wird ab jetzt die Benutzeroberfläche unserer App-Einstellungen vom SettingsFragment erstellt werden.

Wir haben nun die Vorbereitungen abgeschlossen und können mit dem Implementieren der SettingsActivity, welche das SettingsFragment in sich aufnehmen wird, beginnen.

3. Implementieren der SettingsActivity-Klasse

Wir werden jetzt die SettingsActivity unserem Android Studio Projekt hinzufügen. Die neue Activity wird zum Darstellen der Einstellungen unserer App verwendet werden. Sie wird dazu später das SettingsFragment in sich aufnehmen, welches die Erzeugung und Verwaltung der App-Einstellungen übernimmt.

Das Erstellen der SettingsActivity wird in zwei Arbeitsschritten erfolgen:

  1. Erstellen der XML-Layout Datei – In dem layout-Ordner lassen wir von Android Studio eine neue XML-Layout Datei mit dem Dateinamen activity_settings.xml erstellen. Anschließend definieren wir in der erstellten Layout Datei die grafische Benutzeroberfläche unserer Einstellungen-Activity per Android XML-Vokabular.

  2. Erstellen der Java Klassendatei – In dem package-Ordner unseres Projekts lassen wir von Android Studio eine neue Java-Klassendatei mit dem Dateinamen SettingsActivity.java erstellen. Anschließend implementieren wir in der erstellten Java-Klasse die Programmlogik unserer Einstellungen-Activity.

Beginnen wir nun mit dem ersten Arbeitsschritt.

3.1 Erstellen der XML-Layout Datei activity_settings.xml

Wir werden nun für unsere SettingsActivity eine XML-Layout Datei erstellen und in ihr ein einfaches UI-Layout definieren. Dieses Layout werden wir anschließend der Activity als Benutzeroberfläche zuweisen. 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.

Hinweis: Alle XML-Layout Dateien müssen in dem layout-Ordner des Android Projekts abgelegt werden. Nur Layout Dateien die sich im res/layout/ Ordner befinden, werden beim Kompilieren der App in eine View-Ressource umgewandelt.

Wir erstellen nun die XML-Layout Datei activity_settings.xml, mit welcher wir das Aussehen unserer SettingsActivity 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.
create_settings_layout

Erstellen eines Layout Resource File für die activity_settings.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 nur die beiden Felder des Dialogs ausfüllen.

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

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

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 activity_settings.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:

activity_settings.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar_settings_activity"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:elevation="@dimen/toolbar_elevation"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

</LinearLayout>

Mit dem oberen Quellcode definieren wir das UI-Layout für unsere SettingsActivity. Die visuelle Struktur der Activity besteht aus einem LinearLayout– und einem Toolbar–Element. Das LinearLayout-Element ist das Wurzelelement des XML-Layouts und nimmt in sich die Toolbar auf.

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

Das LinearLayout ordnet seine inneren Elemente vertikal an und nimmt als Bildschirmplatz die gesamte zur Verfügung stehende Höhe und Breite ein. Die Toolbar ist momentan das einzige innere Element des LinearLayout. Sie besitzt exakt dieselben Eigenschaften, wie die Toolbar unserer anderen beiden Activities.

Später werden wir ein Fragment, das SettingsFragment, als zweites inneres Element dem LinearLayout hinzufügen. Es wird direkt unterhalb der Toolbar angeordnet werden.

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

activity_settings_layout

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

Nun haben wir das UI-Layout für unsere SettingsActivity angelegt. Als Nächstes werden wir die SettingsActivity-Klasse erstellen, die das eben erstellte XML-Layout zur Erzeugung ihrer Benutzeroberfläche nutzen wird.

3.2 Erstellen der Java Klassendatei SettingsActivity.java

Wir werden nun den zweiten Arbeitsschritt ausführen und die Java Klasse SettingsActivity unserem Android Studio Projekt hinzufügen. Sie wird für das Darstellen der Einstellungen unserer App verwendet werden und das SettingsFragment in sich aufnehmen, welches für die Erzeugung und Verwaltung der App-Einstellungen verantwortlich ist.

Um die neue Klasse SettingsActivity anzulegen, muss eine neue Java Klassendatei in dem Package-Ordner des Projekts erstellt werden. Dafür gibt es zwei Vorgehensweisen: über die obere Menüleiste oder über den Package-Ordner in der Project-Ansicht. Wir werden den zweiten Weg wählen, da er intuitiver und weniger fehleranfällig ist.

Als Erstes muss dafür die Project-Ansicht exakt so wie in Lektion 4 Abschnitt 2 beschrieben aufgeklappt werden. In diesen Package-Ordner werden wir nun die neu Klassendatei mit Hilfe des Create New Class-Dialog von Android Studio anlegen lassen.

Die Klassendatei SettingsActivity.java legen wir nun 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.
create_settings_activity

Erstellen der SettingsActivity-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 SettingsActivity 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.
create_settings_activity_dialog

Den Namen für die SettingsActivity-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 SettingsActivity.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:

SettingsActivity.java

package de.codeyourapp.zitate;

import android.os.Bundle;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.MenuItem;
import android.widget.Toast;

public class SettingsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // View-Elemente aus XML-Layout Datei erzeugen lassen
        setContentView(R.layout.activity_settings);

        // Initialisieren der App Bar und Aktivieren des Up-Buttons
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_settings_activity);
        setSupportActionBar(toolbar);
        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setTitle(getString(R.string.action_settings));

        Toast.makeText(this, "Schritt 1: Die SettingsActivity wurde gestartet.", Toast.LENGTH_SHORT).show();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            onBackPressed();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

}

In Zeile 1 definieren wir zu welchem Package die SettingsActivity-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 8 befinden sich die Import-Anweisungen. Durch sie werden die benötigten externen Klassen eingebunden. Auf diese Weise ist es möglich, auf sie mit ihren einfachen Namen (z.B. Bundle) zuzugreifen, anstelle den vollqualifizierten Namen (z.B. android.os.Bundle) verwenden zu müssen.

In den Zeilen 10 bis 38 wird die Klasse SettingsActivity definiert. Als Super-Klasse wurde die Klasse AppCompatActivity gewählt, welche indirekt von der Klasse Activity abgeleitet ist. Somit besitzt unsere SettingsActivity-Klasse alle Eigenschaften der Activity-Klasse und zusätzliche Kompatibilitätsmechanismen der AppCompatActivity-Klasse, wodurch unsere App auch zu älteren Android Versionen kompatibel bleibt.

Hinweis: Die AppCompatActivity-Klasse ist nicht dem Android Framework zugeordnet, sondern befindet sich in der AndroidX Appcompat Library, welche wir über die Gradle-Datei des app-Moduls in unser Projekt eingebunden haben.

Die SettingsActivity-Klasse besitzt zwei Methoden, die onCreate() und onOptionsItemSelected() Methode. Die onCreate() Methode wird in den Zeilen 13 bis 27 definiert und ist eine Callback-Methode des Android Activity Lifecycles. Sie wird von dem Android System aufgerufen, wenn die Activity erstellt wird. Daher muss jede Activity in Android mindestens diese Callback-Methode implementieren.

In ihr erfolgt die grundlegende Initialisierung der Activity, wie das Instanziieren von Membervariablen und Erzeugen der Benutzeroberfläche. Dies geschieht in Zeile 14, indem die onCreate() Methode der Super-Klasse aufgerufen wird. Sie führt die grundlegende Initialisierung der Activity durch. Würde der Aufruf nicht erfolgen, wäre unsere App nicht lauffähig und eine Exception, die SuperNotCalledException, würde geworfen werden.

In Zeile 17 wird das UI-Layout aus der vorher erstellten XML-Layout Datei geladen. Dazu übergeben wir der setContentView() Methode die Resource-ID der erstellten Layout-Ressource. Auf die entsprechende Ressource wird mit folgender Resource-ID im Code referenziert: R.layout.activity_settings.

In den Zeilen 20 bis 24 wird das Toolbar-Objekt als App Bar für die Activity aktiviert. Dabei wird zuerst die Referenz für die Toolbar-Instanz mit Hilfe der findViewById() Methode angefordert. Nach der Toolbar-Instanz wird mittels der Ressourcen-ID R.id.toolbar_settings_activity gesucht. Anschließend wird die setSupportActionBar() Methode aufgerufen und ihr die erhaltene Toolbar-Instanz übergeben. Auf diese Weise wird das Toolbar-Objekt als App Bar für die SettingsActivity aktiviert.

Für die App Bar wird anschließend der UP-Button aktiviert und ihr Titel festgelegt. Den Titel legen wir mit Hilfe der bereits vorhandenen String-Ressource R.string.action_settings fest, welche den Wert Einstellungen besitzt. Schließlich lassen wir in Zeile 26 eine kurze Toast-Meldung auf dem Android Gerät ausgeben, die über das Starten der SettingsActivity informiert.

Die zweite Methode der SettingsActivity-Klasse wird in den Zeilen 30 bis 36 definiert. Sie trägt den Namen onOptionsItemSelected() und ist für das Überwachen des UP-Buttons verantwortlich. Klickt der Benutzer auf diesen, wird die onBackPressed() Methode aufgerufen, was zum Beenden der SettingsActivity und erneutes Betreten der vorherigen Activity führt.

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

settings_activity_created_code

Die Klassendatei SettingsActivity.java mit dem eingefügten Quellcode

In der oberen Abbildung ist die SettingsActivity.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.

Jetzt haben wir die SettingsActivity-Klasse zusammen mit ihrer XML-Layout Datei erstellt. Unser Android Projekt verfügt damit über eine weitere Activity. Bevor wir die SettingsActivity jedoch starten können, ist noch eine weiterer wichtiger Schritt notwendig. Und zwar muss die neue Activity in der Schaltzentrale unserer Anwendung, dem App Manifest, bekannt gegeben werden. Dies werden wir im nächsten Abschnitt vornehmen.

4. Bekanntgeben der SettingsActivity im App Manifest

Bevor wir die SettingsActivity mittels expliziten Intents starten können, müssen wir sie dem Android System bekanntgeben. Die Bekanntgabe muss in der AndroidManifest.xml Datei, der Schaltzentrale unserer Android Anwendung, erfolgen. Diesen Schritt werden wir jetzt ausführen und die neue Activity bekanntgeben.

Dazu öffnen wir nun die App Manifest-Datei im Editorfenster von Android Studio durch einen Doppelklick auf die entsprechende Datei in der Project-Ansicht. Sie befindet sich in dem app/src/main/ Ordner unseres Android Studio Projekts.

Anschließend fügen wird die markierten Zeilen in den XML-Code der AndroidManifest.xml Datei ein:

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="de.codeyourapp.zitate">

    <!-- Diese Genehmigung wird für das Öffnen von Network Sockets benötigt. -->
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".DetailActivity"
            android:parentActivityName=".MainActivity" >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity" />
        </activity>

        <activity
            android:name=".SettingsActivity" >
        </activity>

    </application>

</manifest>

In dem oberen XML-Code der AndroidManifest.xml Datei ist die SettingsActivity bereits bekanntgegeben worden. Das <application> Element des App Manifests enthält nun drei innere <activity> Elemente, Mit deren Hilfe die jeweilige Activity dem Android System bekanntgegeben wird.

Hinweis: Alle Activities der App müssen durch ein solches <activity> Element repräsentiert sein. Wird eine Activity nicht auf diese Art bekannt gegeben, wird sie vom Android System nicht gesehen und kann niemals ausgeführt werden.

Das Bekanntgeben der neuen Activity, der SettingsActivity, erfolgt in den Zeilen 32 bis 34 über das dritte <activity> Element. Dazu wird dem android:name Attribut der Name der Klasse übergeben, welche die SettingsActivity implementiert. Da in dem <manifest> Element das package Attribut gesetzt ist, kann dafür die Kurzschreibweise (.SettingsActivity) gewählt werden. Dabei wird der Klassenname automatisch von Android Studio an den Package-Namen angehängt.

Die AndroidManifest.xml Datei sollte in Android Studio nun wie folgt aussehen:

android_manifest_settingsactivity

Die AndroidManifest.xml Datei mit den vorgenommenen Änderungen

In der oberen Abbildung ist die AndroidManifest.xml Datei zu sehen. Das dritte <activity> Element wurde bereits eingefügt und ist von einem blauen Rahmen umschlossen (Markierung B). Die erstellte SettingsActivity wurde auf diese Weise dem Android System mittels App Manifest bekannt gegeben. Sie kann jetzt von uns per expliziten Intent gestartet werden.

Im nächsten Abschnitt werden wir genau dies tun und die SettingsActivity von der MainActivity und der DetailActivity aus starten lassen. Ihr Aufruf wird dabei durch einen Klick auf den Einstellungen-Eintrag des Overflow Menu erfolgen.

5. Starten der SettingsActivity per expliziten Intent

Wir werden nun die neue SettingsActivity von der MainActivity und der DetailActivity aus per expliziten Intent starten. Die neue Activity soll immer dann vom Android System aufgerufen werden, wenn der Benutzer auf den Einstellungen-Eintrag des Overflow Menu klickt.

Für das Erfassen von Klicks auf die Einträge des Overflow Menu ist die onOptionsItemSelected() Methode zuständig. Daher müssen wir in diese Methode den Code für das Starten der SettingsActivity einfügen. Der entsprechende Code muss sowohl in die MainActivity– als auch in die DetailActivity-Klasse eingefügt werden. Daraus ergeben sich die folgenden beiden Arbeitsschritte:

  1. Starten der SettingsActivity von der MainActivity aus – Einfügen des Codes zum Starten der SettingsActivity in die onOptionsItemSelected() Methode der MainActivity-Klasse. Dabei wird der bereits bestehende Quelltext teilweise ausgetauscht.

  2. Starten der SettingsActivity von der DetailActivity aus – Einfügen des Codes zum Starten der SettingsActivity in die onOptionsItemSelected() Methode der DetailActivity-Klasse. Dabei wird der bereits bestehende Quelltext teilweise ausgetauscht.

5.1 Starten der SettingsActivity von der MainActivity aus

Wir öffnen nun 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 der MainActivity.java nehmen wir folgende Änderung an der onOptionsItemSelected() Methode vor:

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_get_data:
            // SwipeRefreshLayout anweisen die Fortschrittsanzeige einzublenden
            mSwipeRefreshLayout.setRefreshing(true);
            refreshListView();
            return true;

        case R.id.action_settings:
            startActivity(new Intent(this, SettingsActivity.class));
            return true;

        default:
            // Wenn wir hier ankommen, wurde eine unbekannt Aktion erfasst.
            // Daher erfolgt der Aufruf der Super-Klasse, die sich darum kümmert.
            return super.onOptionsItemSelected(item);

    }
}

Nur die Zeilen 9 bis 11 wurden überarbeitet. Es wird nun die SettingsActivity per explizitem Intent gestartet, wenn der Benutzer auf den Einstellungen-Eintrag des Overflow Menu klickt. Vorher wurde in diesem Fall eine kurze Toast-Meldung auf dem Android Gerät ausgegeben.

Zur besseren Kontrolle ist der gesamte Quellcode der MainActivity.java Datei hier noch einmal aufgeführt worden. Es wurden nur die Zeilen 148 bis 150 überarbeitetet. Zum Betrachten des Quellcodes muss der untere Block aufgeklappt werden:

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 unserer Android Online-Kurse 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 unserer Android Kurse. 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. Dieser besteht aus 35 großen Lektionen und ist als Einstiegskurs konzipiert worden. 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 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 all unseren Android Online-Kursen. Wir werden in Zukunft weitere Android Kurse hinzufügen. Auch auf alle zukünftigen Kurse 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 unserer Android Online-Kurse 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.

Durch das Überarbeiten der onOptionsItemSelected() Methode wird ab jetzt die SettingsActivity gestartet, sobald der Benutzer auf den Einstellungen-Eintrag des Overflow Menu der MainActivity klickt.

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 wurde nur die Methode onOptionsItemSelected() überarbeitet. Sie ist daher als einzige Methode aufgeklappt. Die überarbeiteten Codezeilen sind von einem blauen Rahmen umschlossen (Markierung C).

5.2 Starten der SettingsActivity von der DetailActivity aus

Da auch die DetailActivity über einen Einstellungen-Eintrag im Overflow Menu verfügt, müssen wir auch ihre onOptionsItemSelected() Methode entsprechend überarbeiten.

Wir öffnen dazu die Klassendatei DetailActivity.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 DetailActivity.java nehmen wir folgende Änderung an der onOptionsItemSelected() Methode vor:

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_lookup_author:
            lookupAuthor();
            return true;

        case R.id.action_settings:
            startActivity(new Intent(this, SettingsActivity.class));
            return true;

        default:
            // Wenn wir hier ankommen, wurde eine unbekannt Aktion erfasst.
            // Daher erfolgt der Aufruf der Super-Klasse, die sich darum kümmert.
            return super.onOptionsItemSelected(item);
    }
}

Nur die Zeilen 7 bis 9 wurden überarbeitet. Es wird nun die SettingsActivity per explizitem Intent gestartet, wenn der Benutzer auf den Einstellungen-Eintrag des Overflow Menu klickt. Vorher wurde in diesem Fall eine kurze Toast-Meldung auf dem Android Gerät ausgegeben.

Zur besseren Kontrolle ist der gesamte Quellcode der DetailActivity.java Datei hier noch einmal aufgeführt worden. Es wurden nur die Zeilen 102 bis 104 überarbeitetet. Zum Betrachten des 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 onOptionsItemSelected() Methode wird ab jetzt die SettingsActivity gestartet, sobald der Benutzer auf den Einstellungen-Eintrag des Overflow Menu der DetailActivity klickt.

In Android Studio sollte der Inhalt der DetailActivity.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 DetailActivity.java Klassendatei dargestellt. Es wurde nur die Methode onOptionsItemSelected() überarbeitet. Sie ist daher als einzige Methode aufgeklappt. Die überarbeiteten Codezeilen sind von einem blauen Rahmen umschlossen (Markierung D).

Wir haben nun die MainActivity und DetailActivity so überarbeitet, dass über deren App Bar die SettingsActivity gestartet werden kann. Obwohl bisher erst das Grundgerüst der SettingsActivity implementiert wurde, ist jetzt ein guter Moment die neue Activity das erste Mal zu testen.

Daher werden wir im nächsten Abschnitt unsere App im Emulator auf einem Android Virtual Device ausführen und prüfen, ob die SettingsActivity über das Overflow Menu der MainActivity und DetailActivity gestartet werden kann und korrekt auf dem Android Gerät angezeigt wird.

5.3 Testen der SettingsActivity 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 App reagiert, wenn der Einstellungen-Menüeintrag des Overflow Menu angeklickt wurde.

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_settings_3aa

Nach Anklicken des Einstellungen-Menüeintrags wird jeweils die SettingsActivity gestartet und eine kurze Toast-Meldung zu Testzwecken ausgegeben

In der großen Abbildung ist die SettingsActivity dargestellt. Sie besteht bisher nur aus einer App Bar mit einem Titel und einem Up-Button. Zu Testzwecken wird eine kurze Toast-Meldung ausgegeben, die den Benutzer informiert, dass die neue Activity betreten wurde.

Da nun sichergestellt ist, dass die SettingsActivity über die Einstellungen-Menüeinträge gestartet werden kann und auch ihre App Bar korrekt dargestellt wird, können wir als Nächstes mit dem Implementieren des SettingsFragment beginnen und jenes in die SettingsActivity einbinden.

6. Einbinden des SettingsFragment in die SettingsActivity

Wir werden jetzt das SettingsFragment unserem Android Studio Projekt hinzufügen und in die SettingsActivity einbinden. Das neue Fragment wird das Erzeugen und Verwalten der App-Einstellungen übernehmen.

Hinweis: Ein Fragment repräsentiert ein Verhalten oder einen Teil der Benutzeroberfläche innerhalb einer Activity. Es kann als ein modularer Bestandteil einer Activity vorgestellt werden, der einen eigenen Lebenszyklus besitzt, über eine eigene Ereignisverarbeitung verfügt und während der Ausführung der Activity hinzugefügt oder entfernt werden kann.

Um das SettingsFragment in die SettingsActivity einzubinden, sind folgende drei Arbeitsschritte auszuführen:

  1. Erstellen der Java Klassendatei – In dem package-Ordner unseres Projekts lassen wir von Android Studio eine neue Java-Klassendatei mit dem Dateinamen SettingsFragment.java erstellen. Anschließend implementieren wir in der erstellten Java-Klasse die Programmlogik unseres Einstellungen-Fragments.

  2. Einfügen eines <fragment> Elements in das Layout der SettingsActivity – In die XML-Layout Datei activity_settings.xml fügen wir ein <fragment> Element ein, durch welches das neu erstellte SettingsFragment in die SettingsActivity eingebunden wird.

  3. Entfernen des Test-Codes aus der SettingsActivity-Klasse – Das Einbinden des SettingsFragment in die Activity macht dessen Toast-Meldungen überflüssig. Sie wird daher von uns aus der SettingsActivity-Klasse wieder entfernt.

Beginnen wir nun mit dem ersten Arbeitsschritt.

6.1 Erstellen der Java Klassendatei SettingsFragment.java

Wir werden nun die Java Klasse SettingsFragment unserem Android Studio Projekt hinzufügen. Sie wird für das Erzeugen und Verwalten der App-Einstellungen verantwortlich sein.

Um die neue Klasse SettingsFragment anzulegen, muss eine neue Java Klassendatei in dem Package-Ordner des Projekts erstellt werden. Dafür gibt es zwei Vorgehensweisen: über die obere Menüleiste oder über den Package-Ordner in der Project-Ansicht. Wir werden den zweiten Weg wählen, da er intuitiver und weniger fehleranfällig ist.

Als Erstes muss dafür die Project-Ansicht exakt so wie in Lektion 4 Abschnitt 2 beschrieben aufgeklappt werden. In diesen Package-Ordner werden wir nun die neu Klassendatei mit Hilfe des Create New Class-Dialog von Android Studio anlegen lassen.

Die Klasse SettingsFragment.java legen wir nun 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.
create_settings_fragment

Erstellen der SettingsFragment-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 SettingsFragment 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.
create_settings_fragment_dialog

Den Namen für die SettingsFragment-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 SettingsFragment.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:

SettingsFragment.java

package de.codeyourapp.zitate;

import android.os.Bundle;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import android.widget.Toast;

public class SettingsFragment extends PreferenceFragmentCompat implements
        Preference.OnPreferenceChangeListener {

    @Override
    public void onCreatePreferences(Bundle bundle, String s) {

        Toast.makeText(getContext(), "Schritt 2: Das SettingsFragment wurde gestartet.", Toast.LENGTH_SHORT).show();

    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {

        return true;
    }
}

In Zeile 1 definieren wir zu welchem Package die SettingsFragment-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 befinden sich die benötigten Import-Anweisungen.

In den Zeilen 8 bis 23 wird die Klasse SettingsFragment definiert. Sie ist von der PreferenceFragmentCompat Klasse abgeleitet worden, welche direkt von der Klasse androidx.fragment.app.Fragment abgeleitet ist. Somit besitzt unsere SettingsFragment-Klasse alle Eigenschaften der Fragment-Klasse, zusätzliche Kompatibilitätsmechanismen der AndroidX Library und die Funktionen der Preference-API von Android.

Hinweis: Die PreferenceFragmentCompat-Klasse ist nicht dem Android Framework zugeordnet, sondern befindet sich in der AndroidX Preference Library, welche wir über die Gradle-Datei des app-Moduls in unser Projekt eingebunden haben.

Die SettingsFragment-Klasse besitzt die beiden Methoden onCreatePreferences() und onPreferenceChange(). Die onCreatePreferences() Methode wird in den Zeilen 12 bis 16 definiert. Sie ist für das Erstellen der App-Einstellungen zuständig und wird von der onCreate() Methode beim Erzeugen des Fragments aufgerufen.

Sie ist in ihrer Super-Klasse als abstrakte Methode deklariert und muss daher von uns implementiert werden. Wir werden sie in der nächsten Lektion ausführlich besprechen. Im Moment lassen wir von ihr nur eine kurze Toast-Meldung ausgeben, die den Benutzer über das Betreten des Fragments informiert.

Die onPreferenceChange() Methode wird in den Zeilen 19 bis 22 definiert. Sie ist die einzige Methode des Preference.OnPreferenceChangeListener-Interface, welches von unserer SettingsFragment-Klasse implementiert wird. Sie ist für das Überwachen der App-Einstellungen verantwortlich und wird automatisch vom Android System aufgerufen, sobald eine Einstellung vom Nutzer geändert wurde.

Auch auf sie werden wir in der nächsten Lektion ausführlich eingehen. Im Moment lassen wir von ihr nur den Wert true zurückgeben, wodurch der Preference-API signalisiert wird, dass diese den Wert der entsprechenden Einstellung aktualisieren soll.

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

settings_fragment_created_code

Die Klassendatei SettingsFragment.java mit dem eingefügten Quellcode

In der oberen Abbildung ist die SettingsFragment.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.

Da nun das SettingsFragment implementiert wurde, kann es im nächsten Schritt in das Layout der SettingsActivity eingebunden werden.

6.2 Einfügen eines <fragment> Elements in das SettingsActivity-Layout

Wir fügen nun ein <fragment> Element in die XML-Layout Datei activity_settings.xml ein. Dazu öffnen wir sie im Editorfenster von Android Studio, indem wir doppelt auf ihren Dateinamen im Project Tool Window klicken. Die Datei befindet sich im res/layout/ Ordner unseres Projekts.

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

Dem XML-Code der activity_settings.xml fügen wir nun die folgenden markierten Zeilen hinzu:

activity_settings.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar_settings_activity"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:elevation="@dimen/toolbar_elevation"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    <fragment
        android:id="@+id/fragment_settings_activity"
        android:name="de.codeyourapp.zitate.SettingsFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

Mit dem eingefügtem Code-Block in den Zeilen 18 bis 22 wird das SettingsFragment in das Layout der SettingsActivity eingebunden. Das Layout besteht nun aus einem LinearLayout-Wurzelelement mit zwei inneren Elementen, der Toolbar und dem Fragment.

Für das <fragment> Element haben wir mit android:id=“@+id/fragment_settings_activity“ eine ID anlegen lassen. Über diese ID können wir später zur Laufzeit auf das Fragment von der Activity aus zugreifen.

Anschließend haben wir mit android:name=“de.codeyourapp.zitate.SettingsFragment“ die Klasse angegeben, von der das <fragment> Element implementiert wird. Dabei muss die SettingsFragment-Klasse unbedingt mit ihrem vollqualifizierenden Namen angeben werden.

Mit den beiden übrigen Attributen haben wir die Breite und Höhe des Fragments vorgegeben. Es wird die gesamte Bildschirmbreite nutzen, jedoch nur die Höhe verwenden, die für den eigenen Inhalt benötigt wird.

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

activity_settings_layout_fragment

Die XML-Layout Datei activity_settings.xml mit dem eingefügten Fragment-Element

Durch das eingefügte <fragment> Element (Markierung E) haben wir das SettingsFragment in das XML-Layout der SettingsActivity eingebunden. Als Nächstes müssen wir nun noch den Test-Code aus der SettingsActivity-Klasse entfernen.

6.3 Entfernen des Test-Codes aus der SettingsActivity-Klasse

In der SettingsActivity-Klasse befindet sich noch Test-Code, mit dessen Hilfe eine Toast-Meldung ausgegeben wurde. Diesen Test-Code werden wir nun auskommentieren.

Wir öffnen nun die Klassendatei SettingsActivity.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 SettingsActivity.java kommentieren wir die markierte Zeile aus:

SettingsActivity.java

package de.codeyourapp.zitate;

import android.os.Bundle;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.MenuItem;
import android.widget.Toast;

public class SettingsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // View-Elemente aus XML-Layout Datei erzeugen lassen
        setContentView(R.layout.activity_settings);

        // Initialisieren der App Bar und Aktivieren des Up-Buttons
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_settings_activity);
        setSupportActionBar(toolbar);
        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setTitle(getString(R.string.action_settings));

        //Toast.makeText(this, "Schritt 1: Die SettingsActivity wurde gestartet.", Toast.LENGTH_SHORT).show();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            onBackPressed();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

}

Im Quellcode der SettingsActivity wurde nur die Zeile 26 auskommentiert. Es wird nun keine kurze Toast-Meldung beim Erzeugen der Activity mehr ausgegeben. Der übrige Quellcode bleibt unverändert.

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

settings_activity_created_comment

Der Test-Code wurde in der Klassendatei SettingsActivity.java auskommentiert

In der oberen Abbildung ist die SettingsActivity.java Klassendatei dargestellt. Es wurde nur der Test-Code entfernt, indem die entsprechende Zeile (Markierung F) auskommentiert worden ist.

Mit dieser letzten Änderung haben wir die Arbeiten an der SettingsActivity abgeschlossen. Wir können sie somit in der nächsten Lektion zum Darstellen unserer App-Einstellungen verwenden. Bevor wir dies jedoch tun, werden wir unsere Android App noch einmal zur Sicherheit testen und prüfen, ob das SettingsFragment korrekt eingebunden ist.

7. 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, wie das SettingsFragment in die SettingsActivity eingebunden ist.

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_settings_4aa

Nach Anklicken des Einstellungen-Menüeintrags wird jeweils die SettingsActivity gestartet, in die das SettingsFragment eingebunden wurde. Das Fragment gibt eine kurze Toast-Meldung zu Testzwecken aus.

In der großen Abbildung ist die SettingsActivity dargestellt. Sie besteht bisher nur aus einer App Bar mit einem Titel und einem Up-Button sowie dem SettingsFragment direkt darunter. Zu Testzwecken wird eine kurze Toast-Meldung vom SettingsFragment ausgegeben, die den Benutzer informiert, dass das Fragment korrekt eingebunden wurde.

Nachdem wir nun sichergestellt haben, dass das SettingsFragment korrekt in die SettingsActivity integriert wurde, können wir in der nächsten Lektion mit dem Erstellen der App-Einstellungen beginnen. Diese werden vom nun eingebundenen SettingsFragment aus Preference-Elementen erzeugt und selbständig verwaltet.

Zusammenfassung

In dieser Lektion haben wir eine SettingsActivity unserer Android App hinzugefügt. Die neue Activity ist für das Darstellen unserer App-Einstellungen verantwortlich. Dazu nutzt sie ein SettingsFragment, welches als inneres Element in ihr Layout eingebunden wurde und Teil der Preference-API von Android ist.

Bevor wir das SettingsFragment nutzen konnten, mussten wir einige Vorbereitungsmaßnahmen treffen. Zum einen mussten die beiden AndroidX Preference und Legacy-Preference Libraries in unser Projekt eingebunden werden, zum anderen musste ein Theme für das SettingsFragment vorgegeben werden.

Danach haben wir die SettingsActivity und das SettingsFragment erstellt. Die SettingsActivity wurde zudem im App Manifest unseres Android Projekts bekanntgegeben, damit sie per expliziten Intent von der MainActivity und DetailActivity aus gestartet werden kann.

Abschließend haben wir unsere Android App im Emulator auf einem Android Virtual Device ausgeführt und überprüft, ob die SettingsActivity über das Overflow Menu der App Bar gestartet werden kann und ob das SettingsFragment korrekt in die Activity eingebunden ist.

In der nächsten Lektion werden wir eine Einstellung für unsere Android App bereitstellen. Dazu werden wir ein Preference-Element in einer Ressourcen-Datei anlegen und von dem SettingsFragment daraus eine App-Einstellungen erstellen lassen.

Weiterführende Literatur




Comments 36

  1. Hallo! Super Tutorial!
    Ich hab eine kleien Frage zum Kapitel 7.1 wo die Summary unter dem Settings-Feld angezeigt wird.
    Wenn man einen ganzen Satz voller Settings hat möchte man natürlich nicht für jedes Element „manuell“ findReference aufrufen. Da würde es Sinn machen, für alle Elemente (oder zumindest für alle EditTextPreference-Einträge) das aufzurufen.

    Wie kann ich durch alle Settings-Elemente durch-iterieren?

    Und noch was: PreferenceManager.getDefaultSharedPreferences(this) scheint keine Schreibmethoden zu haben. Wie kann ich „von aussen“ in die Settings reinschreiben? (also angenommen ich will ausserhalb der Setting-activity, zB im Hauptscreen, was in die Settings reinschreiben)

    Danke!!!

  2. Hallo,

    Ich bin dabei, mich mit Android-Programming auseinander zu setzen. Ich habe allerdings ein Problem und ich hätte gedacht, dass Ihr eventuell das Problem lösen könnt, da das Tutorial oberhalb sehr ausführlich und verständlich erklärt wurde. Eigentlich eine simple Sache, allerdings wird das nie irgendwo speziell erklärt, wahrscheinlich da es so einfach ist. Ich würde gerne ein „Save Game“ erstellen, d.h. wenn ich in der „MainActivity“ bin und dann auf Start drücke, dass ich auswählen kann „Neues Spiel“ oder „Spiel laden“. Das Save Game soll speichern wo man aufgehört hat (Bei welcher Activity man stehen geblieben ist, also „keine Werte speichern“ einfach nur der Activity-Stand). Da ich mich nicht mit „Save Games“ auskenne, könntet Ihr mir eventuell weiter helfen?

    l.g.
    Phil

    1. Post
      Author

      Hallo Phil,

      in Lektion 15 dieses Tutorials schreiben wir über den Android Lifecycle und wie man den Zustand von Activities zwischenspeichern kann. Möchte man den zwischengespeicherten Zustand persistent halten, könnte man ihn anschließend in einer kleinen „Save Game“-Datei ablegen, in einer Art CSV-Datei.

      Ich hoffe, das hilft Dir ein bisschen weiter.

      Viele Grüße, Chris

  3. Hi Chris,

    dein Tutorial ist echt Gold wert. Es gibt nichts vergleichbares im Netz.
    Danke für die Mühe und den Einsatz.

    Eine Frage zu diesem Kapitel hätte ich dennoch:
    Gibt es eine Möglichkeit die Schriftfarbe von dem preference_aktienlisten_title zu ändern bzw. von dem was wir eintippen (BMW.DE,…)? Habe es schon mit eigenen Styles probiert, aber bekomme es einfach nicht gebacken.
    Danke nochmal und liebe Grüße
    Jojo

    1. Post
      Author
  4. Hallo,

    ich habe eine Frage. Wie kann ich ein EditTextPreference abhängig von einem ListPreference machen?

    Ich hab eine ListPreference mit zwei Items und möchte die EditTextPreference erst aktivieren wenn Item2 aktiviert ist. Wenn das Item1 aktiv ist soll es einfach grau sein oder von mir aus sogar komplett ausgeblendet. Könntest du mir da bitte helfen?

    Viele Grüße
    Samet

    1. Post
      Author
  5. Hi,

    ich bin begeistert über die Qualität und den Umfang dieses Tutorials. Es ist sehr viel von dem abgedeckt, was mich interessiert. Herzlichen Dank!

    Was mir nicht ganz klar ist, ist die Sinnhaftigkeit des Codeblock B im Abschnitt 5 (// onPreferenceChangeListener sofort aufrufen….). Ich verstehe, dass eine Änderung simuliert und der Event Handler künstlich aufgerufen wird. Aber wieso? Bei mir macht es absolut keinen Unterschied, ob ich das tue oder nicht. Oder liegt es daran, dass ich von PreferenceActivity direkt auf PreferenceFragment umgestellt habe und PreferenceFragment evtl. mehr Automatismen hat? Aber wieso brauchst Du das bei der Checkbox dann nicht?

    Viele Grüße
    Martin

    1. Post
      Author

      Hallo Martin,

      danke für’s Lob!

      Wenn mit der PreferenceActivity gearbeitet wird, muss Codeblock B verwendet werden, damit die Werte der Aktienliste in der Preference-Summary direkt beim ersten Starten der App angezeigt werden. Wird die onPreferenceChange() Methode nicht künstlich beim Erzeugen der Activity aufgerufen, enthält die Preference-Summary einen leeren String. Wie das bei dem PreferenceFragment im Detail aussieht, müsste man nochmal genau nachsehen. Aber es kann durchaus sein, dass dieser umständliche Schritt bei eine PreferenceFragment wegfällt.

      Viele Grüße, Chris

  6. Hallo Chris, es läuft alles ganz prima. Die MainActivity zeigt beim Start die „fest verdrahtete“ Aktienliste, deren Kurswerte ja nicht aktualisiert werden. Habe ich da etwa übersehen, diese Liste zu löschen ?
    Frohe Ostern weiterhin ! Norbert

    1. Post
      Author

      Hallo Norbert,

      die „fest verdrahtete“ Aktienliste wird immer zum Start der App angezeigt. Erst durch manuelles Aktualisieren über das Overflow Menu werden echte Aktiendaten geladen. Man könnte auch die „fest verdrahtete“ Liste direkt beim Startvorgang aktualisieren, indem man den asynchronen Task zum Laden der Aktiendaten in der onCreateView() Methode direkt startet. In dem Android Tutorial haben wir dies aber, aus Platzgründen, nicht umgesetzt.

      Viele Grüße, Chris

      Update: Da bereits einige Leser nach dem automatischen Aktualisieren der Aktiendaten gefragt haben, habe ich ein kleines Video erstellt, in welchem ich zeige wie aktuelle Aktiendaten direkt beim Starten der App angefragt werden können.

      Das Video findet ihr hier: Aktiendaten automatisch bei App-Start aktualisieren [Video]

  7. Wir haben doch Android API Level 10 als minSdkVersion festgelegt. Im Abschnitt 2.2 wird darauf auch hingewiesen.

    Hallo,

    In der AndroidManifest.xml wird an zwei Stellen das Attribut „parentActivityName“ verwendet.

    Vom AndroidStudio bekomme ich dazu folgende Warnung:

    „Attribute parentActivityName is only used in API level 16 and higher“

    Liegt hier ein Versehen vor und kann/soll man diese Warnung mit welchen Folgen ignorieren?

    Gruß, Konrad

    1. Post
      Author

      Hallo Konrad,

      die Warnung ist als Hinweis zu sehen. Wie Du schon schreibst, ist das Attribut parentActivityName erst mit API Level 16 eingeführt worden. Damit unsere App auch auf älteren Android Geräten läuft, wurde zusätzlich mit <meta-data>-Tag gearbeitet.

      <meta-data
              android:name="android.support.PARENT_ACTIVITY"
              android:value="de.programmierenlernenhq.aktiehq.app.MainActivity" />
      

      Es wird dadurch die Kompatibilität für neuere und ältere Android Geräte sichergestellt. Würden wir unsere Android App nur für API Level größer gleich 16 entwickeln, könnten wir auf den <meta-data>-Tag verzichten.

      Bei StackOverflow gibt es weitere sehr interessante Infos zu diesem Thema: Question about parentActivityName attribute

      Viele Grüße, Chris

  8. Hallöle,
    ein ganz tolles Tutorial. Ich würde nur gerne wissen, welche Methoden addPreferenceFromResource und findPreference ersetzt haben? Denn diese werden bei mir als deprecated angezeigt.
    Viele Grüße Kathryn

    1. Post
      Author
  9. Hallo Chris,

    auch von mir nochmal vielen Dank für das klasse Tutorial… 😀

    Allerdings bleibe ich momentan im Kapitel 11.5 hängen. Ich kann android.content.SharedPreferences nicht importieren… der Eintrag bleibt ausgegraut und die Bubble-Info lautet: „Unused import statement.“

    Kannst Du mir vielleicht weiterhelfen? Ohne den Import gehts natürlich auch im SourceCode nicht weiter… 🙁

    Danke und viele Grüße
    Sepp

    1. Post
      Author

      Hallo Sepp,

      das ist ja ein merkwürdiger Fehler. Vielleicht hilft es das build.gradle im app-Ordner zu synchronisieren. Das Gradle kannst du mit Tools -> Android -> Sync Project with Gradle Files synchronisieren.

      Wenn du möchtest, kannst du mir auch deine Projektdateien als ZIP per E-Mail senden. Ich schau dann mal drüber. Die E-Mail findest du über das Impressum.

      Viele Grüße, Chris

    2. Post
      Author
    3. Noch für’s Protokoll:

      Die ausgegrauten Import-Statements in Android-Studio bedeuten zunächst einmal nicht, dass die entsprechende Klasse nicht importiert wird, sondern – siehe auch „Bubble Info: Unused import statement“ – dass die Klasse gar nicht verwendet wird, genau genommen also auch nicht importiert werden muss. Ein Tippfehler bei der Verwendung des Klassennamens (s.u.) ist eine Möglichkeit, dieses Verhalten hervorzurufen.

      Bei mir kommen z.B. regelmäßig durch irgendwelche Tests automatisch import-Anweisungen in den Quelltext. Wenn sich die Tests als unbrauchbar erweisen und ich die Anweisungen im Quelltext wieder lösche, vergesse ich regelmäßig, auch die import-Statements zu löschen (da hilft die graue Schrift dann sehr dabei, den Code sauber zu halten 😉 )

      Weiß jemand (Chris?), ob „unused import statements“ beim Erzeugen des Java-Bytecodes ignoriert werden?

    4. Post
      Author

      Hallo Reinhard,

      ich habe mal zu dem Thema unused import statements etwas recherchiert. Auf Stackoverflow bin ich fündig geworden.

      Does an unused import declaration eat memory, in Java?

      Die unused import statements werden beim Kompilieren entfernt und nicht in den Bytecode übersetzt. Man sollte sie aber trotzdem entfernen, wenn sie nicht mehr gebraucht werden.

      Viele Grüße, Chris

  10. Wenn ich die „Liste der Finanzinstrumente“ ändere in dem ich z.B. den DAX entferne, zeigt er mir das noch an, aber wenn ich aus den Einstellungen raus gehe und wieder rein ist der DAX wieder da.
    Irgendwie speichert er nicht die Änderung und ich hab jetzt schon alles mehrfach kontrolliert.
    Habt ihr vllt eine Idee woran das liegen könnte?

    1. Post
      Author

      Hallo Mathias,

      schwer zu sagen ohne Quellcode. Wenn du möchtest, kannst du mir deine Projektdateien per E-Mail zusenden. Ich werde dann mal drüber schauen, vielleicht kann ich den Fehler finden. Die E-Mail Adresse kannst du im Impressum nachschauen.

      UPDATE: Der Fehler konnte gefunden werden. In der Methode onPreferenceChange der Klasse EinstellungenActivity wurde als Rückgabewert false zurück gegeben. Es muss aber true zurück gegeben werden, sonst werden die Änderungen nicht gespeichert.

      Viele Grüße, Chris

  11. Moin,
    erstmal, wirklich ansehnliches Tutorial!
    Ab 4.5 mit dem Einfügen der Anweisung „addPreferencesFromResource(R.xml.preferences)“ in die onCreate Methode, kommt beim Testen der App immer die Nachricht: „Unfortunately AktieHQ has stopped“ wenn ich auf Settings klicke… An was kann das liegen? Liegt es vllt an der veralteten Anweisung?
    Viele Grüße und Danke im Voraus für die Hilfe 🙂

    1. Post
      Author

      Hallo Robin,

      an der veralteten Anweisung sollte es nicht liegen, da der Code in genau dieser Form bei vielen funktioniert hat.

      Gibt dir Android Studio eine Fehlermeldung aus? Um die Fehlermeldung in Android Studio zu sehen, darfst du nicht auf den OK-Button im „Unfortunately AktieHQ has stopped“-Dialog klicken.

      Weiterhin kannst du mit dem Debugger einen Breakpoint an der Codezeile „addPreferencesFromResource(R.xml.preferences);“ setzen und dann die App im Debug-Modus mit dem grünen Käfer-Symbol ausführen. Dann im Debug-Modus untersuchen was zu dem Crash führt.

      Linkvorschläge für das Debugging:
      https://developer.android.com/tools/debugging/debugging-studio.html
      https://www.youtube.com/watch?v=Vo5PXWnKtQ4

      Viele Grüße, Chris

    2. Salü!

      Ich hatte den gleichen Fehler und hab die Ursache gefunden. Sie liegt im preferences.xml:

      ...
      
          android:layout_width="match_parent"
          android:layout_height="match_parent"&gt;
      
      ...
      

      Der PreferenceScreen Tag ist geschlossen, trotzdem kommen zwei Attribute nach. Sind die beiden weg, funktioniert’s.

      AndroidStudio zeigt das auch an mit dem Highlighting.

    3. Post
      Author

      Hallo André,

      danke für die Hilfe!

      Ohh, dass der Fehler beim Erstellen des Tutorials nicht aufgefallen ist. Ich werde die betreffenden Stellen in der Anleitung demnächst korrigieren.

      Viele Grüße und nochmals Danke!, Chris

  12. Pingback: Android Tutorial: Mit impliziten Intent eine andere App aufrufen

  13. Ich muss sagen, dies ist das beste online, gratis Android Tutorial, das ich bisher gefundne habe.
    Ich freue mich schon auf eine Fortsetzung. Danke!

    1. Post
      Author
  14. Ich muss wirklich sagen, dies ist das beste online, gratis Android Tutorial, das es gibt. Alles ist sehr übersichtlich erklärt mit Bildern, Text. 😀
    Ich hoffe, die Reihe wird bald fortgesetzt!

    1. Post
      Author

      Hallo Tobias,

      vielen Dank für dein Lob. Es freut mich sehr, wenn das Tutorial verständlich ist. Die Reihe wird weiter fortgesetzt.

      Viele Grüße, Chris

  15. Pingback: Android Tutorial: Activities und Intents in Android

Schreibe einen Kommentar

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