Utiliser la barre d'application

La barre d'application supérieure offre un emplacement fixe en haut de la fenêtre de l'application pour afficher les informations et actions de l'écran actuel.

Exemple de barre d'application supérieure
Image 1. Exemple de barre d'application supérieure.

La propriété de la barre d'application varie en fonction des besoins de votre application. Quand ? à l'aide de fragments, la barre d'application peut être implémentée ActionBar appartenant par l'activité hôte ou par une barre d'outils dans la mise en page de votre fragment.

Si tous vos écrans utilisent la même barre d'application qui se trouve toujours en haut et couvre toute la largeur de l'écran, utilisez un thème fourni une barre d'action hébergée par l'activité. L'utilisation de barres d'application de thème permet de maintenir une apparence cohérente et permet d'héberger les menus d'options et Bouton "Haut".

Utilisez une barre d'outils hébergée par le fragment si vous souhaitez mieux contrôler la taille, l'emplacement et l'animation de la barre d'application sur plusieurs écrans. Par exemple, vous aurez peut-être besoin d'une barre d'application pouvant être réduite ou d'une barre d'application qui ne s'étend que sur la moitié de la largeur de l'écran et qui est centrée verticalement.

Différentes situations nécessitent des approches différentes pour des éléments tels que le gonflage les menus et de répondre à l'interaction de l'utilisateur. Comprendre les différentes et l'utilisation de la meilleure pour votre application vous permet de gagner du temps pour garantir le bon fonctionnement de votre application.

Les exemples de cette section font référence à un ExampleFragment contenant un profil modifiable. Le menu défini par XML suivant est gonflé dans la barre d'application du fragment :

<!-- 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>

Le menu contient deux options: l'une pour accéder à un écran de profil et une autre pour enregistrer les modifications apportées au profil.

Barre d'application appartenant à une activité

La barre d'application appartient le plus souvent à l'activité de l'hôte. Lorsque la barre d'application appartient à une activité, les fragments peuvent interagir avec elle en remplaçant les méthodes du framework appelées lors de la création du fragment.

S'enregistrer auprès de l'activité

Vous devez informer le système que le fragment de votre barre d'application participe à l'insertion du menu d'options. Pour ce faire, appelez setHasOptionsMenu(true) dans la méthode onCreate(Bundle) de votre fragment, comme illustré dans l'exemple suivant :

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) indique au système que votre fragment souhaite recevoir des rappels liés aux menus. Lorsqu'une commande liée au menu comme un clic, la méthode de gestion des événements appelé d'abord l'activité avant d'être appelé sur le fragment.

Cependant, ne vous fiez pas à cet ordre dans votre logique d'application. Si les l'activité héberge plusieurs fragments, chaque fragment peut fournir des éléments de menu options. Dans ce cas, l'ordre de rappel dépend de l'ordre dans où les fragments sont ajoutés.

Gonfler le menu

Pour fusionner votre menu dans le menu d'options de la barre d'application, remplacez onCreateOptionsMenu() dans votre fragment. Cette méthode reçoit le menu de la barre d'application actuelle et un MenuInflater en tant que paramètres. Utilisez le système de gonflage du menu pour créer une instance du menu de votre fragment, puis fusionnez-le dans le menu actuel, comme illustré dans l'exemple suivant :

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);
    }
}

L'image 2 montre le menu mis à jour.

Le menu d&#39;options contient désormais votre fragment de menu
Image 2. Le menu d'options contient désormais votre fragment de menu.

Gérer les événements de clic

Chaque activité et fragment participant au menu d'options peut réagissent aux gestes. Le rôle onOptionsItemSelected() reçoit l'élément de menu sélectionné en tant que paramètre et renvoie une valeur booléenne pour indiquer si l'appui est actif. Une fois qu'un activité ou fragment renvoie true à partir de onOptionsItemSelected(), mais pas les autres fragments participants reçoivent le rappel.

Dans votre implémentation de onOptionsItemSelected(), utilisez une instruction switch sur l'itemId de l'élément de menu. Si l'élément sélectionné vous appartient, gérez la pression de façon appropriée et renvoyez true pour indiquer que l'événement de clic est géré. Si l'élément sélectionné n'est pas appelez l'implémentation super. Par défaut, le super renvoie false pour permettre le traitement du menu.

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);
        }

    }

}

Modifier le menu de manière dynamique

Placez la logique pour masquer ou afficher un bouton, ou modifier l'icône dans onPrepareOptionsMenu() Cette méthode est appelée juste avant l'affichage du menu.

Reprenons l'exemple précédent. Le bouton Enregistrer doit être invisible jusqu'à ce que l'utilisateur commence à apporter des modifications et doit disparaître une fois que l'utilisateur a enregistré les modifications. L'ajout de cette logique à onPrepareOptionsMenu() crée le menu s'affiche correctement:

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);
    }
}

Lorsque vous devez mettre à jour le menu, par exemple lorsqu'un utilisateur appuie sur le bouton Modifier pour modifier les informations du profil, appelez invalidateOptionsMenu() sur l'activité de l'hôte pour demander au système d'appeler onCreateOptionsMenu(). Après l'invalidation, vous pouvez effectuer les mises à jour dans onCreateOptionsMenu(). Une fois le menu est gonflé, le système appelle onPrepareOptionsMenu() et met à jour le menu pour refléter l'état actuel du fragment.

Kotlin

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

Java

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

Barre d'application appartenant à un fragment

Si la plupart des écrans de votre application n'ont pas besoin d'une barre d'application, ou si une écran a besoin d'une barre d'application différente des autres, vous pouvez ajouter Toolbar à votre la mise en page du fragment. Toutefois, vous pouvez ajouter un Toolbar n'importe où dans votre la hiérarchie des vues du fragment, vous le conservez généralement en haut l'écran. Pour utiliser Toolbar dans votre fragment, fournissez un ID et obtenir une référence à celui-ci dans votre fragment, comme pour toute autre vue. Vous pouvez également envisager d'animer la barre d'outils à l'aide de CoordinatorLayout comportements.

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

Lorsque vous utilisez une barre d'application appartenant à un fragment, Google recommande d'utiliser Toolbar directement. N'utilisez pas setSupportActionBar() et les API de menu Fragment, qui ne conviennent qu'aux barres d'application appartenant à une activité.

Gonfler le menu

La méthode pratique Toolbar de inflateMenu(int) utilise l'ID d'une ressource de menu comme paramètre. Pour gonfler une ressource de menu XML dans votre barre d'outils, transmettez resId à cette méthode, comme indiqué dans l'exemple suivant :

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);
    }

}

Pour gonfler une autre ressource de menu XML, appelez de nouveau la méthode avec le resId du nouveau menu. Les nouveaux éléments de menu sont ajoutés au menu, et les éléments de menu existants ne sont ni modifiés, ni supprimés.

Si vous souhaitez remplacer l'ensemble de menus existant, effacez le menu avant appeler inflateMenu(int) avec le nouvel ID de menu, comme indiqué ci-dessous ; Exemple:

Kotlin

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

Java

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

        viewBinding.myToolbar.getMenu().clear()

    }

}

Gérer les événements de clic

Vous pouvez transmettre un OnMenuItemClickListener directement à la barre d'outils à l'aide de la méthode setOnMenuItemClickListener(). Cet écouteur est appelé lorsque l'utilisateur sélectionne un élément de menu. à l'aide des boutons d'action présentés à la fin de la barre d'outils de dépassement associé. L'élément MenuItem sélectionné est transmis à la méthode onMenuItemClick() de l'écouteur et peut être utilisé pour consommer l'action, comme indiqué dans l'exemple suivant :

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;
            }
        });
    }
}

Modifier le menu de manière dynamique

Lorsque votre fragment est propriétaire de la barre d'application, vous pouvez modifier Toolbar à l'adresse comme n'importe quelle autre vue.

Reprenons l'exemple précédent. L'option de menu Enregistrer devrait être sont invisibles tant que l'utilisateur n'a pas commencé à apporter des modifications. à nouveau lorsque vous appuyez dessus:

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);
    }

}

Le cas échéant, le bouton de navigation s'affiche au début de la barre d'outils. Définir une icône de navigation la fait apparaître dans la barre d'outils. Vous pouvez également définir un onClickListener() propre à la navigation, appelé lorsque l'utilisateur clique sur le bouton de navigation, comme illustré dans l'exemple suivant :

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.
            }
        });
    }
}