Im letzten Kapitel zur Reihe “ESP Controller ansprechen” haben wir die Android App “ESPTutorialApp” umgeschrieben so das wir eine Seitennavigation mit Icons haben.
Nun möchten wir für die kommenden Seiten das Layout vorbereiten, das heißt das wir im Backend die Fragmente erstellen und die Layouts festlegen.
Was sind Fragmente?
Mit Fragmenten können wir eine Seite in unser Android App gliedern. Vorallem können wir diese Fragmente wiederverwenden und haben somit einen größeren Benefit unser Arbeit.
Wie bindet man Fragmente ein?
Für das einbinden von Fragmenten benötigt man in der View einen Platzhalter. Dieses ist das FrameLayout. Initial wird dem FrameLayout ein Fragment übergeben welches beim starten der App angezeigt werden soll.
Schritt 1 – erzeugen eines Fragments für die Startseite
Zunächst erzeugen wir uns ein neues Fragment, hierzu navigieren wir über das Kontextmenü des Projektes “New” > “Fragment” > “Fragment (Blank)”.
Dieses Fragment soll beim starten der App angezeigt werden und allgemeine Informationen zu der App und der Benutzung anzeigen.
Nun werden wir dieses Fragment in der View “content_navigation.xml” definieren.
<?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" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context=".NavigationActivity" tools:showIn="@layout/app_bar_navigation"> <FrameLayout android:id="@+id/container" android:name="de.draegerit.esptutorialapp.HauptseiteFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
Damit dieses Fragment jedoch beim starten angezeigt wird, müssen wir dieses in der Methode “onCreate” definieren.
Dazu legen wir uns ein neues Feld in der Klasse “NavigationActivity” an.
Fragment hauptseiteFragment; @Override protected void onCreate(Bundle savedInstanceState) { ... hauptseiteFragment = new HauptseiteFragment(); updateFragment(hauptseiteFragment); ... }
Zusätzlich benötigen wir eine Methode um das Fragment auf der View zu wechseln, da wir diese Methode jedoch für jede Aktion in dem NavigationsMenü benötigen werden wir den Code in eine extra Methode auslagern.
private void updateFragment(Fragment fragment) { FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.beginTransaction() .replace(R.id.container, fragment) .addToBackStack(null) .commit(); }
Schritt 2 – Interface auslagern
Als nächstes muss man das interne Interface “OnFragmentInteractionListener” aus der Klasse “HauptseiteFragment” auslagern denn dieses wird für jedes Fragment welches wir für unsere App erzeugen benötigt.
Warum die Anwendung AndroidStudio dieses Interface für jedes Fragment neu erstellt ist mir unklar.
/** * This interface must be implemented by activities that contain this * fragment to allow an interaction in this fragment to be communicated * to the activity and potentially other fragments contained in that * activity. * <p> * See the Android Training lesson <a href= * "http://developer.android.com/training/basics/fragments/communicating.html" * >Communicating with Other Fragments</a> for more information. */ public interface OnFragmentInteractionListener { // TODO: Update argument type and name void onFragmentInteraction(Uri uri); }
Des Weiteren werden wir in diesem Zuge die Klasse etwas aufräumen. Die Kommentare, Felder und einige Methoden in der Klasse werden wir für dieses Tutorial nicht benötigen.
package de.draegerit.esptutorialapp; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class HauptseiteFragment extends Fragment { private OnFragmentInteractionListener mListener; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_hauptseite, container, false); } @Override public void onAttach(Context context) { super.onAttach(context); if (context instanceof OnFragmentInteractionListener) { mListener = (OnFragmentInteractionListener) context; } else { throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener"); } } @Override public void onDetach() { super.onDetach(); mListener = null; } }
Zusätzlich müssen wir unser Klasse “NavigationActivity” dieses neue Interface implementieren lassen.
... public class NavigationActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, OnFragmentInteractionListener { ...
Durch dieses einbinden des Interfaces müssen wir die Methode “onFragmentInteraction” einbinden.
@Override public void onFragmentInteraction(Uri uri) {}
Wenn wir diesen Schritt erledigt haben können wir nun unsere Anwendung bauen und installieren. Nun sollten Wir auf unser App den Text “Hello blank fragment” sehen.
Schritt 3 – weitere Fragmente für die Seiten erstellen
Nun nachdem wir unser erstes Fragment für die Startseite eingebaut haben, wollen wir für jeden unserer Menüpunkte ein Fragment erstellen. (Hier verfahren wir wie bei der Hauptseite.)
D.h. wir erstellen für den Menüpunkt “fotoresistor”, “imprint” und “privacy notice”.
Aus diesen neuen Klassen entfernen wir mindestens das Interface “OnFragmentInteractionListener” denn wir haben dieses ja bereits ausgelagert.
Schritt 4 – Seitenwechsel implementieren
Wir haben nun für jeden unserer Menüpunkte und für die Hauptseite ein Fragment erzeugt. Um den Seitenwechsel zu vollziehen müssen wir die Methode “onNavigationItemSelected” in der Klasse “NavigationActivity” wiefolgt anpassen.
@Override public boolean onNavigationItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.nav_fotoresistor) { updateFragment(fotoresistorFragment); } else if (id == R.id.nav_imprint) { updateFragment(imprintFragment); } else if (id == R.id.nav_privacynotice) { updateFragment(privacyNoticeFragment); } DrawerLayout drawer = findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; }
Wenn wir (bzw. der Benutzer der App) auf einen Menüpunkt klicken dann wird die Methode ausgeführt und wir erhalten zusätzlich das MenuItem welches ausgewählt wurde. Als erstes lesen wir von diesem MenuItem die ID, wenn zbsp. die ID gleich “R.id,nav_fotoresistor” ist dann aktualisieren wir das FrameLayout und setzen das Fragment für den Fotowiderstand. Zum Schluss wird noch das Menü geschlossen. Wenn auf kein Menüpunkt geklickt wird (quasi auf eine freie Fläche) so passiert nichts.
Menüführung in der AndroidApp ESPTutorialApp
Zum starten des animierten GIF’s bitte auf das Bild klicken.
Download
Fazit & Ausblick
Wir haben nun in diesem Tutorial die Seiten für den Fotowiderstand, das Impressum sowie für die Datenschutzerklärung angelegt. Als nächstes werden wir nun die Seite für den Fotowiderstand mit leben befüllen und uns die Daten auf einem Liniendiagramm anzeigen lassen.
Echt tolle Tutorial!
Wann kommt der nächste Teil?
Hi,
der 5. Teil ist in arbeit jedoch sind mir so einige andere Beiträge dazwischen gekommen.
Aber ich werde demnächst auch dort weiter machen.
Gruß,
Stefan Draeger