Programmier Tutorial - Apps für Android entwickeln - Das SwipeRefreshLayout in Android

Programmier Tutorial – Teil 14: Daten neu laden mit SwipeRefreshLayout


Mit einem SwipeRefreshLayout können wir unserer Android App sehr einfach das Swipe to Refresh UI-Pattern hinzufügen. Dieses erkennt selbständig die Swipe Down-Geste (Nach Unten-Wischen) und führt anschließend das Aktualisieren des verknüpften Inhalts durch.

Dieses Verhalten wird von vielen populären Apps genutzt, wie Gmail, Facebook, Twitter und diversen Sport-Apps.

Wird vom oberen Ende einer Liste der Inhalt nach unten geschoben, erscheint ein Lade-Symbol und der Inhalt wird aktualisiert. Sobald der Inhalt aktualisiert wurde, wird das Symbol ausgeblendet und der neue Inhalt angezeigt.

In dieser Lektion werden wir unserer App genau diese Funktion hinzufügen. Dazu sind folgende Schritte notwendig:

  1. Refactoring – Auslagern des Aktualisieren-Quellcodes in eine eigene Methode.
  2. Anpassen des Layouts – Ersetzen des FrameLayouts durch das SwipeRefreshLayout in der fragment_aktienliste.xml Layout-Datei.
  3. Einrichten des Swipe-Refresh – Registrieren eines OnRefreshListeners für das SwipeRefreshLayout und Aktualisieren des Inhalts unserer Aktien- bzw. Indize-Liste.

Nun wünschen wir euch viel Spaß bei dem vierzehnten Teil unseres großen Android Tutorials. Los geht’s!

1. Was ist das SwipeRefreshLayout in Android?

Android Apps Programmieren Online-Kurs

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Das SwipeRefreshLayout ist, wie der Name schon erkennen lässt, ein Layout, mit dem es leicht möglich ist, den umschlossenen Inhalt durch die Swipe Down-Geste neu zu laden.

Die Klasse SwipeRefreshLayout ist von der ViewGroup-Klasse abgeleitet und somit ein View-Objekt. Sie wurde mit Android KitKat eingeführt und mit dem Android Lollipop Release der v4 Android Support Library erweitert.

Mit ihr ist es leicht möglich das Swipe to Refresh Pattern für Listen, bspw. für einen ListView, umzusetzen.

Das SwipeRefreshLayout sollte immer dann verwendet werden, wenn Benutzer den Inhalt eines Views mit einer vertikalen Wisch-Geste (swipe gesture) aktualisieren können.

Die Implementierung des SwipeRefreshLayouts in das eigene Android Projekt ist sehr einfach. Möchte man eine Swipe Down-Geste für ein View-Objekt erkennen, muss der View einfach in dem SwipeRefreshLayout-Element gelagert werden.

In unserem Fall werden wir das SwipeRefreshLayout um unseren bereits vorhandenen ListView hüllen. Um auf die Wisch-Geste zu reagieren, implementieren wir das SwipeRefreshLayout.OnRefreshListener-Interface.


Wird eine Swipe Down-Geste auf dem View ausgeführt, wird die onRefresh-Methode gestartet, in der wir das Aktualisieren unseres Inhalts, der Aktienliste, durchführen werden.

1.1 Implementieren eines SwipeRefreshLayouts in Android

Mit den folgenden drei Schritten wird ein SwipeRefreshLayout in eine Android App eingebunden:

  1. Das SwipeRefreshLayout muss das zu aktualisierende View-Element umschließen.
  2. In der Activity oder dem Fragment, wo der View instanziiert wird, muss der OnRefreshListener für den SwipeRefreshLayout-View mit der Methode setOnRefreshListener() registriert werden.
  3. Weiterhin muss das Interface SwipeRefreshLayout.OnRefreshListener in der Activity oder dem Fragment implementiert werden, durch Überschreiben der onRefresh()-Methode.

Das hört sich vielleicht etwas kompliziert an, ist aber, wie wir im Laufe dieser Lektion sehen werden, sehr einfach.

Wichtig ist, dass dem SwipeRefreshLayout nur ein direktes Kindelement (View) zugewiesen wird. Andernfalls kann es zu Problemen bei dem Aktualisieren des umschlossenen Inhalts kommen.

Damit das SwipeRefreshLayout in der eigenen Android App verwendet werden kann, muss die v4 Android Support Library eingeschlossen werden.

Da diese in der v7 Android Support Library inkludiert ist, müssen wir dem build.gradle unseres Projekts keine weitere Dependency hinzufügen. Siehe folgende Diskussion auf StackOverflow.

Weitere sehr nützliche Informationen über das SwipeRefreshLayout könnt ihr hier finden:

Soviel zur Theorie. Nun möchten wir das SwipeRefreshLayout in unsere App einfügen. Dazu werden wir als Nächstes den Quellcode etwas aufräumen.

2. Refactoring – Auslagern des Aktualisieren-Quelltextes

Dieser Schritt ist sehr einfach und soll die Lesbarkeit und Wiederverwendbarkeit unseres Quelltextes verbessern.

Bisher können wir unsere Aktiendaten mit Hilfe des Aktualisieren-Buttons im Overflow-Menu der Action Bar neu laden.

Da wir den Aktualisieren-Vorgang auch mit dem SwipeRefreshLayout starten möchten, bietet es sich an für das Aktualisieren unserer Daten in beiden Fällen die gleiche Methode zu verwenden.

Daher werden wir den bisherigen Aktualisieren-Quellcode, der sich momentan in der onOptionsItemSelected-Methode befindet, in eine eigene Methode auslagern. Die neue Methode soll aktualisiereDaten() heißen.

Für diesen Arbeitsschritt öffnen wir als Erstes die AktienlisteFragment.java Datei.

Nach der onCreateView-Methode fügen wir die neue Methode aktualisiereDaten() ein. Die neue Methode enthält den relevanten Quelltext aus der onOptionsItemSelected-Methode.

AktienlisteFragment.java

public void aktualisiereDaten() {
  // Erzeugen einer Instanz von HoleDatenTask
  HoleDatenTask holeDatenTask = new HoleDatenTask();

  // Auslesen der ausgewählten Aktienliste aus den SharedPreferences
  SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
  String prefAktienlisteKey = getString(R.string.preference_aktienliste_key);
  String prefAktienlisteDefault = getString(R.string.preference_aktienliste_default);
  String aktienliste = sPrefs.getString(prefAktienlisteKey, prefAktienlisteDefault);

  // Auslesen des Anzeige-Modus aus den SharedPreferences
  String prefIndizemodusKey = getString(R.string.preference_indizemodus_key);
  Boolean indizemodus = sPrefs.getBoolean(prefIndizemodusKey, false);

  // Starten des asynchronen Tasks und Übergabe der Aktienliste
  if (indizemodus) {
    String indizeliste = "^GDAXI,^TECDAX,^MDAXI,^SDAXI,^GSPC,^N225,^HSI,XAGUSD=X,XAUUSD=X";
    holeDatenTask.execute(indizeliste);
  }
  else {
    holeDatenTask.execute(aktienliste);
  }

  // Den Benutzer informieren, dass neue Aktiendaten im Hintergrund abgefragt werden
  Toast.makeText(getActivity(), "Aktiendaten werden abgefragt!", Toast.LENGTH_SHORT).show();
}

Da wir nun eine eigene Methode für das Aktualisieren unserer Finanzdaten definiert haben, können wir den entsprechenden Quellcode aus der onOptionsItemSelected-Methode löschen und an dessen Stelle den Methodenaufruf einfügen:

AktienlisteFragment.java

public boolean onOptionsItemSelected(MenuItem item) {
  // Wir prüfen, ob Menü-Element mit der ID "action_daten_aktualisieren"
  // ausgewählt wurde, holen die Finanzdaten und geben eine Meldung aus
  int id = item.getItemId();
  if (id == R.id.action_daten_aktualisieren) {

    aktualisiereDaten();

    return true;
  }

  return super.onOptionsItemSelected(item);
}

In unserem Android Projekt sollte die Klasse AktienlisteFragment jetzt folgendermaßen aussehen:

swiperefreshlayout methode auslagern

Auslagern des Aktualisieren-Quelltextes in die aktualisiereDaten() Methode

Die beiden blauen Rahmen in der oberen Abbildung kennzeichnen die veränderten Codestellen. Der Rahmen A umschließt die onOptionsItemSelected-Methode von der aus wir die neue Methode aktualisiereDaten() aufrufen.

In Rahmen B ist unser Aktualisieren-Quelltext enthalten, den wir in die aktualisiereDaten-Methode ausgelagert haben.

Ihr solltet jetzt das Android Projekt kompilieren und die App auf eurem Android Gerät oder im Emulator ausführen. Die App sollte nun wie gewohnt funktionieren, da wir nur den Quellcode ausgelagert haben und sonst keine Änderungen am Quelltext vorgenommen haben.

Da wir nun den Aktualisieren-Vorgang mit der neu angelegten Methode aktualisiereDaten() starten können, sind wir bereit für den nächsten Arbeitsschritt. Dazu werden wir eine kleine Veränderung an der Layout-Datei fragment_aktienliste.xml vornehmen, um das SwipeRefreshLayout darin einzufügen.

3. Einfügen des SwipeRefreshLayouts in die Layout-Datei

In diesem Arbeitsschritt tauschen wir das bisherige FrameLayout aus und ersetzen es durch das SwipeRefreshLayout.

Dazu öffnen wir die Datei fragment_aktienliste.xml unseres Projektes in Android Studio.

In dieser XML-Layout Datei beschreiben wir das Layout des AktienlisteFragments unserer Android App.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

An dem vorhandenen Quellcode müssen wir nur zwei Änderungen vornehmen:

  1. Austauschen des FrameLayouts und Ersetzen mit dem android.support.v4.widget.SwipeRefreshLayout.
  2. Hinzufügen einer ID für das SwipeRefreshLayout-Element.

In dem folgendem Quellcode sind die beiden Änderungen an der fragment_aktienliste.xml Datei bereits durchgeführt worden. Die veränderten Zeilen sind gelb markiert:

fragment_aktienliste.xml

<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".AktienlisteFragment"
    android:id="@+id/swipe_refresh_layout_aktienliste">

    <ListView
        android:id="@+id/listview_aktienliste"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.v4.widget.SwipeRefreshLayout>

Wie an dem Pfad zum SwipeRefreshLayout zu erkennen ist, befindet sich dieses Layout in der v4 Android Support Library. Dadurch ist sichergestellt, dass dieses Layout auch mit älteren Android Apps kompatibel ist.

Dem SwipeRefreshLayout haben wir die id mit der Bezeichnung swipe_refresh_layout_aktienliste zugewiesen. Es ist uns somit leicht möglich mit der Methode findViewById() nach diesem View-Element zu suchen.

In Android Studio sollte die Datei fragment_aktienliste.xml jetzt wie folgt aussehen:

swiperefreshlayout xml layout

Das SwipeRefreshLayout umschließt den ListView, der unsere Aktiendaten in Listenform anzeigt

Als Nächstes werden für das SwipeRefreshLayout-Objekt einen OnRefreshListener registrieren und damit unsere Aktiendaten mit einer Swipe Down-Geste aktualisieren lassen.

4. Registrieren eines OnRefreshListener für das SwipeRefreshLayout

Jetzt haben wir alle Vorbereitungen abgeschlossen und können dem SwipeRefreshLayout die gewünschte Funktion zuweisen. Dazu werden wir an einigen Stellen in der AktienlisteFragment.java Datei Änderungen vornehmen.

Wir werden folgende Änderungen bzw. Ergänzungen durchführen:

  1. Importieren der SwipeRefreshLayout-Klasse.
  2. Anlegen der Membervariable mSwipeRefreshLayout in der AktienlisteFragment-Klasse.
  3. Auslesen des View-Objekts aus dem Layout des Fragments und Registrieren eines OnRefreshListeners für das View-Objekt.
  4. Das SwipeRefreshLayout über den Abschluss des Aktualisieren-Vorgangs informieren.

4.1 Importieren der SwipeRefreshLayout-Klasse

Da wir die Klasse SwipeRefreshLayout verwenden, müssen wir diese noch mit Hilfe von Import-Anweisungen bekannt machen.

Dazu fügen wir folgende Import-Anweisungen in die AktienlisteFragment-Klasse ein:

AktienlisteFragment.java

import android.support.v4.widget.SwipeRefreshLayout;

Als Nächstes legen wir eine Membervariable vom Typ SwipeRefreshLayout an.

4.2 Anlegen der Membervariable mSwipeRefreshLayout

Die neue Membervariable deklarieren wir ganz am Anfang der AktienlisteFragment-Klasse. An dieser Stelle haben wir bereits die Membervariable mAktienlisteAdapter definiert. Eine Zeile weiter unten legen wir die neue Membervariable mSwipeRefreshLayout vom Typ SwipeRefreshLayout an.

Wir verwenden dazu folgenden Quellcode:

AktienlisteFragment.java

SwipeRefreshLayout mSwipeRefreshLayout;

Da die Membervariable mSwipeRefreshLayout in der Klasse SwipeRefreshLayout liegt, können wir innerhalb dieser Klasse und auch von der inneren Klasse HoleDatenTask aus auf sie zugreifen.

Dies ist notwendig, da wir später in der Klasse HoleDatenTask dem SwipeRefreshLayout-Objekt mitteilen, dass der Vorgang des Aktualisierens abgeschlossen wurde.

4.3 Auslesen des View-Objekts aus dem Layout des Fragments und Registrieren eines OnRefreshListeners

Dies ist der entscheidende Arbeitsschritt. Wir fügen dem View einen Listener zu, der die Eingaben des Benutzers überwacht und die Daten aktualisiert, sobald eine Swipe Down-Geste erkannt wurde.

Dazu fügen wir den folgenden Quellcode in die onCreateView-Methode der Klasse AktienlisteFragment unmittelbar vor der return-Anweisung ein:

AktienlisteFragment.java

mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_refresh_layout_aktienliste);

mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
     @Override
     public void onRefresh() {
         aktualisiereDaten();
     }
});

Mit Zeile 1 lesen wir das View-Element aus der View-Hierarchie unseres AktienlisteFragments aus. Wir benutzen dafür die findViewById-Methode und suchen nach der id, die wir für das SwipeRefreshLayout-Element vergeben haben.

Als Ergebnis der Suche erhalten wir das entsprechende View-Element zurück, welches wir noch in den SwipeRefreshLayout-Datentyp umwandeln, bevor wir es in der eben angelegten Membervariable mSwipeRefreshLayout abspeichern.

Für dieses View-Objekt registrieren wir mit den Zeilen 3 bis 8 einen OnRefreshListener mit der setOnRefreshListener-Methode. Dazu implementieren wir das Interface SwipeRefreshLayout.OnRefreshListener, indem wir die abstrakte Methode onRefresh() des Interfaces definieren.

Die Methode onRefresh() führt das Aktualisieren der Aktienliste durch. Dazu ruft sie unsere ausgelagerte Methode aktualisiereDaten() auf.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Mit diesen 8 Zeilen Code haben wir den OnRefreshListener für den SwipeRefreshLayout-View registriert. Unsere Android App reagiert somit auf die Swipe Down-Geste und aktualisiert die Aktienliste sobald die Geste ausgeführt wird.

Als Nächstes müssen wir dem SwipeRefreshLayout-View mitteilen, dass der Aktualisieren-Vorgang abgeschlossen wurde, falls dem so ist.

4.4 Das SwipeRefreshLayout über den Abschluss des Aktualisieren-Vorgangs informieren

Das Aktualisieren wird durch ein Lade-Icon symbolisiert. Dieses Symbol wird solange eingeblendet, bis dem SwipeRefreshLayout-View mitgeteilt wird, dass der Vorgang abgeschlossen wurde.

Diese Mitteilung muss am Ende des Aktualisierens erfolgen. In unserem Fall endet dieser Vorgang in der onPostExecute-Methode der inneren Klasse HoleDatenTask.

Daher fügen wir am Ende der onPostExecute-Methode die folgende Codezeile ein:

AktienlisteFragment.java

mSwipeRefreshLayout.setRefreshing(false);

Mit dieser Anweisung teilen wir dem SwipeRefreshLayout-View mit, das der Refresh-Prozess abgeschlossen wurde, wir also mit dem Aktualisieren der Daten fertig sind und die neuen Daten in der Aktienliste angezeigt werden.

Da wir an einigen Stellen Veränderungen in der Datei AktienlisteFragment.java vorgenommen haben, kann es leicht zu Missverständnissen kommen. Daher solltet ihr noch einmal in Ruhe den kompletten Quellcode der Klasse anschauen und mit eurem vergleichen:

AktienlisteFragment.java (als ZIP-Datei gepackt)

Weitere sehr hilfreiche Informationen über das SwipeRefreshLayout könnt ihr hier finden:

5. Testen der Android App und des SwipeRefreshLayouts

Alle notwendigen Änderungen an den Quelltexten unseres Android Projekts sind vorgenommen. Nun wollen wir unsere App testen. Dazu installieren wir die Anwendung auf unser angeschlossenes Android Gerät (Smartphone oder Tablet) und lassen sie dort ausführen.

Um die App auf dem Android Gerät starten zu können, müssen alle Schritte von Teil 3 des Android Tutorials befolgt worden sein.

Hier noch einmal in Kürze die wichtigsten Arbeitsschritte.

Zuerst schließen wir unser Android Gerät an den PC an und stellen eine Verbindung über die ADB (Android Debug Bridge) her. Danach klicken wir auf das Run 'app'-Symbol. Unser Android Projekt wird dadurch neu erstellt und auf dem angeschlossenen Gerät ausgeführt.

Das Run 'app'-Symbol befindet sich in der oberen Menüleiste, siehe folgende Abbildung:

android studio project avd run

Android App über das Run App-Symbol starten

Nach einigen Momenten öffnet sich der Choose Device-Dialog. In ihm nehmen wir die folgenden Einstellungen vor:

  1. Radio Button Choose a running device aktivieren
  2. Das angeschlossene Android Gerät auswählen
  3. Mit einem Klick auf den OK-Button die Installation unserer App auf das Gerät starten
android choose device

Auswählen des angeschlossenen Android Geräts zum Aufspielen unserer App

Der Dialog schließt sich und unsere Android App wird auf das angeschlossene Gerät übertragen und installiert. Die Installation dauert nur einen kurzen Augenblick und verläuft fast unbemerkt im Hintergrund. Danach wird unsere App automatisch gestartet.

5.1 Testen des SwipeRefreshLayouts unserer Android App

Unsere App ist gestartet und die Aktienliste mit den Finanzinstrumenten wird angezeigt. Jetzt führen wir die Swipe Down-Geste mit einem Finger aus. Dazu drücken wir den Finger auf ein Element der Liste und ziehen den Finger nach unten.

Nach einer gewissen Strecke erscheint das Lade-Symbol, das den Refresh-Prozess repräsentiert. Das Symbol wird von oben in den View eingeblendet und bewegt sich entsprechend unserer Fingerbewegung.

Der Aktualisieren-Vorgang startet, wenn der Pfeil des Lade-Symbols Schwarz ist und wir den Finger vom Display unseres Android Geräts lösen. Tun wir dies, wird die onRefresh-Methode aufgerufen, von der aus wir mit dem Aktualisieren der Aktiendaten beginnen. Sobald die Daten neu geladen worden sind, werden sie in dem ListView unserer Android App angezeigt.

Der eben beschriebene Vorgang ist in der unteren Abbildung dargestellt:

swiperefreshlayout android app

Das SwipeRefreshLayout erkennt die Swipe Down-Geste und aktualisiert den ListView

In der Abbildung ist das Lade-Symbol des SwipeRefreshLayouts zu erkennen. In unserem Fall besitzt es das Standard-Aussehen. Das Aussehen kann jedoch sehr einfach verändert und an spezielle Vorgaben angepasst werden. Mit der Methode setColorSchemeResources() kann bspw. die Farbe des Pfeils vorgegeben werden.

5.2 Video – Daten per Swipe Down-Geste in Android aktualisieren

Nun möchten wir unsere Android App auch einmal in der aktuellen Entwicklungsstufe im Video sehen. Dazu haben wir das folgende kurze Video erstellt, in dem die neue Funktion unserer App vorgestellt wird:

In dem oberen Video führen wir zwei Aktualisierungen per Swipe Down-Geste durch. Dazu drücken wir mit einem Finger auf ein oberes Element der Liste und halten den Finger gedrückt. Anschließend ziehen wir den Finger nach unten.

Dabei erscheint das Lade-Symbol des SwipeRefreshLayouts am oberen Bildschirmrand. Es bewegt sich entsprechend unserer Zieh-Bewegung und besitzt einen animierten grauen Pfeil. Sobald wir unseren Finger weit genug nach unten bewegt haben, ändert der Pfeil seine Farbe von Grau zu Schwarz. Dies symbolisiert, dass beim Loslassen der Aktualisieren-Vorgang gestartet wird.

Lösen wir den Finger vom Display, startet das Aktualisieren und die neuen Aktiendaten werden von unserer Android App im Hintergrund geladen. Den Vorgang können wir mit einer weiteren Swipe Down-Geste erneut wiederholen.

Zusammenfassung

In der vierzehnten Lektion unseres großen Android Tutorials haben wir das SwipeRefreshLayout von Android näher kennengelernt. Es wurde mit Android KitKat eingeführt und mit dem Android Lollipop Release der v4 Android Support Library erweitert, wodurch es auch zu älteren Android Versionen kompatibel ist.

Mit dem SwipeRefreshLayout sind wir in der Lage Daten per Swipe Down-Geste neu zu laden. Um diese Funktionalität in unsere Android App zu integrieren, waren folgende Arbeitsschritte notwendig:

  1. Refactoring – Auslagern des Aktualisieren-Quellcodes in eine eigene Methode.
  2. Anpassen des Layouts – Ersetzen des FrameLayouts durch das SwipeRefreshLayout in der fragment_aktienliste.xml Layout-Datei.
  3. Einrichten des Swipe-Refresh – Registrieren eines OnRefreshListeners für das SwipeRefreshLayout und Aktualisieren des Inhalts unserer Aktien- bzw. Indize-Liste.

Nachdem wir diese drei Arbeitsschritte ausgeführt hatten, haben wir unsere Android Anwendung ausführlich getestet und die neue Funktion in einem Video vorgestellt. Unsere Finanz-App lässt sich jetzt viel einfacher und intuitiver bedienen, was die Benutzerfreundlichkeit deutlich verbessert.

In der nächsten Lektion werden wir den Android Life Cycle kennenlernen und das Verhalten unserer Android App verbessern, indem wir den Zustand unserer Anwendung zwischenspeichern und bei Bedarf erneut laden.



Schreibe einen Kommentar

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