01 – Fragment verstehen
Kurseinführung
Dieser Kurs setzt Android-Grundkenntnisse voraus.
Ohne diese Grundlagen ist es schwer, weiterzumachen.
Fragment wird als „Fragment“ oder „Teilstück“ übersetzt.
Eigentlich ist „Fragment“ korrekter.
Es ist ein in eine Activity eingebettetes UI-Teilstück.
Es ermöglicht Anwendungen, große Bildschirmflächen sinnvoller und effizienter zu nutzen.
Daher eignet es sich besonders gut für Tablets.
Es ähnelt einer Activity sehr: Es hat ein eigenes Layout und einen eigenen Lebenszyklus.
Man kann es als eine Mini-Activity betrachten.
Wenn wir eine Nachrichten-App entwickeln,
würden wir bei einem Smartphone-Bildschirm vielleicht so vorgehen:
Eine Listen-Activity, und beim Antippen öffnet sich eine Detail-Activity für den Artikel.
Auf einem Tablet würde das aber große leere Bereiche hinterlassen, was nicht optimal ist.
Ein besserer Entwurf ist, Liste und Details in zwei Fragmenten innerhalb derselben Activity unterzubringen.
Tablet-Emulator erstellen
Um unsere Tablet-App besser testen zu können, erstellen wir einen Tablet-Emulator.

02 – Erstes Beispiel mit Fragment
Zwei Fragmente zu einer Activity hinzufügen und den Platz gleichmäßig aufteilen.
Erstellen Sie ein neues Projekt namens FragmentFirst.
Fügen Sie zwei Layouts hinzu: eines für das linke Fragment
newlist.xml
und eines für das rechte Fragment, newdetail.xml.
Linkes Fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/buttondialog"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Handelskrieg USA-China 2018" />
</LinearLayout>Code-Sprache: HTML, XML (xml)
Rechtes Fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0ddb97"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Nachrichteninhalt Nachrichteninhalt" />
</LinearLayout>Code-Sprache: HTML, XML (xml)
Fragment-Klasse hinzufügen
Fügen Sie ein NewListFragment hinzu.
Erben Sie von android.support.v4.app.Fragment.
Überschreiben Sie dann die Methode onCreateView, damit dieses Fragment das newlist-XML verwendet.
public class NewListFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.newlist,container,false);
return view;
}
}Code-Sprache: PHP (php)
Fügen Sie das Nachrichtendetail-Fragment auf die gleiche Weise hinzu.
NewDetailFragment erbt ebenfalls von
android.support.v4.app.Fragment.
public class NewDetailFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.newdetail,container,false);
return view;
}
}Code-Sprache: PHP (php)
Fragmente im Haupt-Activity-Layout aufrufen
Verwenden Sie das Attribut android:name=“com.foxdevelop.„, um festzulegen, welches Fragment verwendet werden soll.
Beim Hinzufügen eines Fragments im Hauptlayout darf die ID nicht fehlen.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/newlist_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:name="com.foxdevelop.www.fragmentfirst.NewListFragment"
/>
<fragment
android:id="@+id/newdetail_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:name="com.foxdevelop.www.fragmentfirst.NewDetailFragment"
/>
</LinearLayout>Code-Sprache: HTML, XML (xml)
03 – Fragmente dynamisch hinzufügen
Die wahre Stärke von Fragmenten liegt darin, dass sie während der Laufzeit dynamisch zu einer Activity hinzugefügt werden können.
Indem wir je nach Situation Fragmente dynamisch hinzufügen, können wir viel flexiblere Oberflächen gestalten.
Zum Beispiel in unserer Nachrichten-App: Manche Artikel sind Bildnachrichten, manche Textnachrichten, manche Videonachrichten. Je nach Typ kann ein anderes Fragment-Layout geladen werden.
Wir fügen ein new_picture-Layout hinzu.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/birdsee"
/>
</LinearLayout>Code-Sprache: HTML, XML (xml)
Um es zu unterscheiden, zeigt es einfach ein Bild an.
Bild-Fragment-Klasse hinzufügen
public class NewImageFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.new_picture,container,false);
return view;
}
}Code-Sprache: PHP (php)
FrameLayout im Hauptlayout verwenden
Hier verwenden wir ein FrameLayout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/newlist_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:name="com.foxdevelop.www.fragmentfirst.NewListFragment"
/>
<FrameLayout
android:id="@+id/framelayout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
></FrameLayout>
</LinearLayout>Code-Sprache: HTML, XML (xml)
Zwei Buttons links hinzufügen
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/buttondialog"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Handelskrieg USA-China 2018" />
<Button
android:id="@+id/buttonpicture"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Bildnachricht" />
</LinearLayout>Code-Sprache: HTML, XML (xml)
Button-Events in der Haupt-Activity setzen
Indem wir Click-Events auf die Buttons setzen, können wir je nach Button dynamisch verschiedene Fragmente laden.
package com.foxdevelop.www.fragmentfirst;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Events an die zwei Buttons binden
Button b1 = (Button)findViewById(R.id.buttonarticle);
b1.setOnClickListener(this);
Button b2 = (Button)findViewById(R.id.buttonpicture);
b1.setOnClickListener(this);
}
@Override
public void onClick(View view) {
// Verschiedene Fragmente je nach Button setzen
switch (view.getId())
{
case R.id.buttonarticle:
setFragement(new NewDetailFragment());
break;
case R.id.buttonpicture:
setFragement(new NewImageFragment());
break;
default:
break;
}
}
// Diese Methode setzt das Fragment für das FrameLayout
public void setFragement(Fragment fragement) {
FragmentManager fragementManager = getSupportFragmentManager();
// Transaktion starten
android.support.v4.app.FragmentTransaction fragmentTransaction = fragementManager.beginTransaction();
fragmentTransaction.replace(R.id.framelayout,fragement);// FrameLayout das übergebene Fragment nutzen lassen
fragmentTransaction.commit();
}
}Code-Sprache: JavaScript (javascript)

04 – Back-Stack mit Fragmenten verwenden
Was ein Back-Stack ist, haben wir im Grundlagenkurs behandelt.
Im vorherigen Beispiel stellen wir fest, dass beim Drücken der Zurück-Taste die App direkt die Haupt-Activity verlässt und das Programm beendet. Das ist nicht das gewünschte Verhalten; wir möchten, dass die Zurück-Taste zum vorherigen Fragment zurückkehrt.
Fragmente den Back-Stack unterstützen zu lassen, ist eigentlich sehr einfach.
Man muss die Transaktion einfach zum Back-Stack hinzufügen.
// Diese Methode setzt das Fragment für das FrameLayout
public void setFragement(Fragment fragement) {
FragmentManager fragementManager = getSupportFragmentManager();
// Transaktion starten
android.support.v4.app.FragmentTransaction fragmentTransaction = fragementManager.beginTransaction();
fragmentTransaction.replace(R.id.framelayout,fragement);// FrameLayout das übergebene Fragment nutzen lassen
fragmentTransaction.addToBackStack(null);// Transaktion zum Back-Stack hinzufügen
fragmentTransaction.commit();
}Code-Sprache: JavaScript (javascript)
05 – Kommunikation zwischen Fragment und Activity
Fragmente sind zwar in Activities eingebettet, aber tatsächlich ist ihre Beziehung nicht so eng.
Unser Fragment und unsere Activity existieren als unabhängige Klassen.
Es gibt keine direkte Möglichkeit für sie zu kommunizieren.
Um die Kommunikation zu erleichtern,
bietet der FragmentManager eine Methode ähnlich wie findViewById, um eine Fragment-Instanz aus dem Layout zu holen.
getFragmentManager android.support.v4.app.Fragment
muss gecastet werden. Das wurde im Buch nicht erwähnt.
Wenn Sie das Paket android.support.v4.app.Fragment (also das v4-Paket) importiert haben
import android.support.v4.app.Fragment;
müssen Sie beim Erhalten des FragmentManagers Folgendes verwenden:
FragmentManager fm = getSupportFragmentManager();
Das entsprechende Fragment muss ebenfalls das richtige Paket importieren!
// Fragment-Instanz in der onCreate-Methode der Activity abrufen
NewListFragment newListFragment = (NewListFragment)getSupportFragmentManager().findFragmentById(R.id.newlist_fragment);
Toast.makeText(this, newListFragment.getId()+"xxxx",Toast.LENGTH_LONG).show();Code-Sprache: JavaScript (javascript)

Activity aus dem Fragment abrufen
// Activity aus dem Fragment abrufen
MainActivity mainActivity = (MainActivity) getActivity();
Toast.makeText(getContext(), mainActivity.getTitle(),Toast.LENGTH_LONG).show();Code-Sprache: JavaScript (javascript)
Sie können die Methode getActivity() aufrufen.

06 – Lebenszyklus von Fragmenten
Der Lebenszyklus eines Fragments ist im Wesentlichen derselbe wie der einer Activity.
Fragmente haben ebenfalls vier Zustände.
Laufend, Pausiert, Gestoppt, Zerstört.
1. Laufender Zustand: Das Fragment ist sichtbar und die zugehörige Activity läuft, daher ist auch das Fragment aktiv.
2. Pausierter Zustand
Wenn eine andere Activity, die den Bildschirm nicht vollständig ausfüllt, oben auf den Stack gelegt wird, geht das sichtbare Fragment, das sie verwaltet, in den pausierten Zustand über.
3. Gestoppter Zustand
Wenn eine Activity in den gestoppten Zustand übergeht, gehen auch ihre zugehörigen Fragmente in den gestoppten Zustand. Oder wenn Sie mit FragmentTransaction remove oder replace ein Fragment aus einer Activity entfernen und vor dem Commit addToBackStack aufrufen, geht es ebenfalls in den gestoppten Zustand.
Kurz gesagt: Ein Fragment im gestoppten Zustand ist für den Benutzer unsichtbar und kann jederzeit vom System entsorgt werden.
4. Zerstörter Zustand
Fragmente hängen immer von Activities ab. Wenn also eine Activity zerstört wird, gehen auch ihre Fragmente in den zerstörten Zustand. Oder wenn Sie remove oder replace verwenden, ohne addToBackStack vor dem Commit aufzurufen, wird das Fragment ebenfalls zerstört.
Wie bei Activities bietet auch Fragment eine Reihe von Callback-Methoden, die jeden Schritt des Lebenszyklus abdecken. Fast alles, was eine Activity hat, hat auch ein Fragment.
Gleichzeitig bietet Fragment auch einige zusätzliche Callback-Methoden.
Fragment