Fragment

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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert