Mit der AppBar arbeiten

Die obere App-Leiste bietet einen einheitlichen Bereich oben im App-Fenster, an dem Informationen und Aktionen vom aktuellen Bildschirm angezeigt werden können.

ein Beispiel für eine obere App-Leiste
Abbildung 1: Ein Beispiel für eine obere App-Leiste.

Die Inhaberschaft der App-Leiste hängt von den Anforderungen Ihrer App ab. Wenn Sie Fragmente verwenden, kann die App-Leiste als ActionBar implementiert werden, das der Hostaktivität oder einer Symbolleiste innerhalb des Layouts des Fragments gehört.

Wenn alle Ihre Bildschirme dieselbe App-Leiste verwenden, die sich immer oben befindet und die Breite des Bildschirms einnimmt, verwenden Sie eine vom Design bereitgestellte Aktionsleiste, die von der Aktivität gehostet wird. Die Verwendung von Themen-App-Leisten sorgt für ein einheitliches Erscheinungsbild und bietet einen Ort, an dem Optionsmenüs und eine Nach-oben-Schaltfläche gehostet werden können.

Wenn Sie die Größe, Platzierung und Animation der App-Leiste auf mehreren Bildschirmen besser steuern möchten, können Sie eine vom Fragment gehostete Symbolleiste verwenden. Sie benötigen beispielsweise eine minimierbare App-Leiste oder eine, die nur die halbe Breite des Bildschirms einnimmt und vertikal zentriert ist.

Unterschiedliche Situationen erfordern unterschiedliche Ansätze, um beispielsweise die Menüs aufzublähen oder auf Nutzerinteraktionen zu reagieren. Wenn Sie die verschiedenen Ansätze kennen und den besten für Ihre Anwendung verwenden, sparen Sie Zeit und können dafür sorgen, dass die Anwendung ordnungsgemäß funktioniert.

Die Beispiele in diesem Thema verweisen auf ein ExampleFragment, das ein bearbeitbares Profil enthält. Durch das Fragment wird das folgende XML-definierte Menü in der App-Leiste aufgebläht:

<!-- sample_menu.xml -->
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/action_settings"
        android:icon="@drawable/ic_settings"
        android:title="@string/settings"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/action_done"
        android:icon="@drawable/ic_done"
        android:title="@string/done"
        app:showAsAction="ifRoom|withText"/>

</menu>

Das Menü enthält zwei Optionen: eine zum Aufrufen eines Profilbildschirms und eine zum Speichern aller vorgenommenen Profiländerungen.

App-Leiste für Aktivitäten

Die App-Leiste gehört in der Regel dem Host. Wenn die App-Leiste einer Aktivität gehört, können Fragmente mit der App-Leiste interagieren, indem Framework-Methoden überschrieben werden, die während der Fragmenterstellung aufgerufen werden.

Mit Aktivität registrieren

Sie müssen das System darüber informieren, dass Ihr App-Leistenfragment in der Grundgesamtheit des Optionsmenüs enthalten ist. Rufen Sie dazu setHasOptionsMenu(true) in der onCreate(Bundle)-Methode des Fragments auf, wie im folgenden Beispiel gezeigt:

Kotlin

class ExampleFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)
    }
}

Java

public class ExampleFragment extends Fragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }
}

setHasOptionsMenu(true) teilt dem System mit, dass das Fragment menübezogene Callbacks erhalten möchte. Wenn ein menübezogenes Ereignis auftritt, z. B. ein Klick, wird die Methode zur Ereignisbehandlung zuerst für die Aktivität und dann für das Fragment aufgerufen.

Verlassen Sie sich in Ihrer Anwendungslogik jedoch nicht auf diese Reihenfolge. Wenn in derselben Aktivität mehrere Fragmente gehostet werden, kann jedes Fragment Menüoptionen bereitstellen. In diesem Fall hängt die Callback-Reihenfolge von der Reihenfolge ab, in der die Fragmente hinzugefügt werden.

Speisekarte aufblähen

Wenn Sie das Menü mit dem Optionsmenü der App-Leiste zusammenführen möchten, überschreiben Sie onCreateOptionsMenu() im Fragment. Diese Methode empfängt das aktuelle Menü der App-Leiste und einen MenuInflater als Parameter. Erstellen Sie mit dem Menü-Inflater eine Instanz des Menüs des Fragments und führen Sie sie dann wie im folgenden Beispiel mit dem aktuellen Menü zusammen:

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.sample_menu, menu)
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
       inflater.inflate(R.menu.sample_menu, menu);
    }
}

Abbildung 2 zeigt das aktualisierte Menü.

Das Optionsmenü enthält jetzt Ihr Menüfragment.
Abbildung 2: Das Optionsmenü enthält jetzt Ihr Menüfragment.

Klickereignisse verarbeiten

Jede Aktivität und jedes Fragment im Optionsmenü kann auf Berührungen reagieren. Das onOptionsItemSelected()-Element des Fragments empfängt das ausgewählte Menüelement als Parameter und gibt einen booleschen Wert zurück, der angibt, ob die Berührung erfolgt. Sobald eine Aktivität oder ein Fragment true von onOptionsItemSelected() zurückgibt, erhalten keine anderen teilnehmenden Fragmente den Callback.

Verwende in der Implementierung von onOptionsItemSelected() eine switch-Anweisung für itemId des Menüpunkts. Wenn Sie das ausgewählte Element haben, gehen Sie entsprechend vor und geben Sie true zurück, um anzugeben, dass das Klickereignis verarbeitet wird. Wenn das ausgewählte Element nicht Ihnen gehört, rufen Sie die Implementierung super auf. Standardmäßig gibt die super-Implementierung false zurück, damit die Menüverarbeitung fortgesetzt werden kann.

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.action_settings -> {
                // Navigate to settings screen.
                true
            }
            R.id.action_done -> {
                // Save profile changes.
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_settings:  {
                // Navigate to settings screen.
                return true;
            }
            case R.id.action_done: {
                // Save profile changes.
                return true;
            }
            default:
                return super.onOptionsItemSelected(item);
        }

    }

}

Speisekarte dynamisch ändern

Legen Sie die Logik fest, um eine Schaltfläche ein- oder auszublenden oder das Symbol in onPrepareOptionsMenu() zu ändern. Diese Methode wird unmittelbar vor dem Einblenden des Menüs aufgerufen.

In Fortführung des vorherigen Beispiels sollte die Schaltfläche Speichern erst sichtbar sein, wenn der Nutzer mit der Bearbeitung beginnt, und nach dem Speichern wieder verschwinden. Wenn Sie onPrepareOptionsMenu() diese Logik hinzufügen, wird das Menü korrekt dargestellt:

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onPrepareOptionsMenu(menu: Menu){
        super.onPrepareOptionsMenu(menu)
        val item = menu.findItem(R.id.action_done)
        item.isVisible = isEditing
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onPrepareOptionsMenu(@NonNull Menu menu) {
        super.onPrepareOptionsMenu(menu);
        MenuItem item = menu.findItem(R.id.action_done);
        item.setVisible(isEditing);
    }
}

Wenn Sie das Menü aktualisieren müssen, z. B. wenn ein Nutzer die Schaltfläche Bearbeiten drückt, um die Profilinformationen zu bearbeiten, rufen Sie invalidateOptionsMenu() für die Hostaktivität auf, um das System dazu aufzufordern, onCreateOptionsMenu() aufzurufen. Nach der Entwertung können Sie die Aktualisierungen in onCreateOptionsMenu() vornehmen. Sobald sich das Menü aufgebläht hat, ruft das System onPrepareOptionsMenu() auf und aktualisiert das Menü entsprechend dem aktuellen Status des Fragments.

Kotlin

class ExampleFragment : Fragment() {
    ...
    fun updateOptionsMenu() {
        isEditing = !isEditing
        requireActivity().invalidateOptionsMenu()
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    public void updateOptionsMenu() {
        isEditing = !isEditing;
        requireActivity().invalidateOptionsMenu();
    }
}

App-Leiste des Fragments

Wenn für die meisten Bildschirme in Ihrer App keine App-Leiste erforderlich ist oder ein Bildschirm eine andere App-Leiste als die anderen benötigt, können Sie dem Fragmentlayout ein Toolbar hinzufügen. Obwohl Sie ein Toolbar an einer beliebigen Stelle in der Ansichtshierarchie des Fragments hinzufügen können, bleibt es in der Regel oben auf dem Bildschirm. Wenn Sie Toolbar in Ihrem Fragment verwenden möchten, geben Sie eine ID an und rufen Sie wie bei jeder anderen Ansicht in Ihrem Fragment einen Verweis darauf ab. Sie können die Symbolleiste auch mithilfe von CoordinatorLayout-Verhaltensweisen animieren.

<androidx.appcompat.widget.Toolbar
    android:id="@+id/myToolbar"
    ... />

Bei Verwendung einer App-Leiste, die einem Fragment gehört, empfiehlt Google, die Toolbar APIs direkt zu verwenden. Verwenden Sie nicht setSupportActionBar() und die Fragment-Menü-APIs, die nur für aktivitätseigene App-Leisten geeignet sind.

Speisekarte aufblähen

Die Toolbar-Convenience-Methode inflateMenu(int) verwendet die ID einer Menüressource als Parameter. Um eine XML-Menüressource in der Symbolleiste hinzuzufügen, übergeben Sie resId an diese Methode, wie im folgenden Beispiel gezeigt:

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        ...
        viewBinding.myToolbar.inflateMenu(R.menu.sample_menu)
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        ...
        viewBinding.myToolbar.inflateMenu(R.menu.sample_menu);
    }

}

Um eine weitere XML-Menüressource zu erweitern, rufen Sie die Methode noch einmal mit dem resId des neuen Menüs auf. Die neuen Menüpunkte werden dem Menü hinzugefügt und die vorhandenen werden weder geändert noch entfernt.

Wenn Sie den vorhandenen Menüsatz ersetzen möchten, löschen Sie das Menü, bevor Sie inflateMenu(int) mit der neuen Menü-ID aufrufen, wie im folgenden Beispiel gezeigt:

Kotlin

class ExampleFragment : Fragment() {
    ...
    fun clearToolbarMenu() {
        viewBinding.myToolbar.menu.clear()
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    public void clearToolbarMenu() {

        viewBinding.myToolbar.getMenu().clear()

    }

}

Klickereignisse verarbeiten

Sie können ein OnMenuItemClickListener-Objekt mit der Methode setOnMenuItemClickListener() direkt an die Symbolleiste übergeben. Dieser Listener wird aufgerufen, wenn der Nutzer über die Aktionsschaltflächen am Ende der Symbolleiste oder im zugehörigen Überlauf ein Menüelement auswählt. Der ausgewählte MenuItem wird an die Methode onMenuItemClick() des Listeners übergeben und kann wie im folgenden Beispiel zum Verarbeiten der Aktion verwendet werden:

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        ...
        viewBinding.myToolbar.setOnMenuItemClickListener {
            when (it.itemId) {
                R.id.action_settings -> {
                    // Navigate to settings screen.
                    true
                }
                R.id.action_done -> {
                    // Save profile changes.
                    true
                }
                else -> false
            }
        }
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        ...
        viewBinding.myToolbar.setOnMenuItemClickListener(item -> {
            switch (item.getItemId()) {
                case R.id.action_settings:
                    // Navigate to settings screen.
                    return true;
                case R.id.action_done:
                    // Save profile changes.
                    return true;
                default:
                    return false;
            }
        });
    }
}

Speisekarte dynamisch ändern

Wenn das Fragment Inhaber der App-Leiste ist, können Sie Toolbar zur Laufzeit wie jede andere Ansicht ändern.

Um auf das vorherige Beispiel zurückzukommen: Die Menüoption Speichern sollte erst sichtbar sein, wenn der Nutzer mit der Bearbeitung beginnt, und wieder verschwinden, wenn Sie darauf tippen:

Kotlin

class ExampleFragment : Fragment() {
    ...
    fun updateToolbar() {
        isEditing = !isEditing

        val saveItem = viewBinding.myToolbar.menu.findItem(R.id.action_done)
        saveItem.isVisible = isEditing

    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    public void updateToolbar() {
        isEditing = !isEditing;

        MenuItem saveItem = viewBinding.myToolbar.getMenu().findItem(R.id.action_done);
        saveItem.setVisible(isEditing);
    }

}

Falls vorhanden, wird die Navigationsschaltfläche am Anfang der Symbolleiste angezeigt. Wenn du ein Navigationssymbol in der Symbolleiste festlegst, wird diese sichtbar. Sie können auch eine navigationsspezifische onClickListener() festlegen, die aufgerufen wird, wenn der Nutzer auf die Navigationsschaltfläche klickt, wie im folgenden Beispiel gezeigt:

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        ...
        myToolbar.setNavigationIcon(R.drawable.ic_back)

        myToolbar.setNavigationOnClickListener { view ->
            // Navigate somewhere.
        }
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        ...
        viewBinding.myToolbar.setNavigationIcon(R.drawable.ic_back);
        viewBinding.myToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Navigate somewhere.
            }
        });
    }
}