Catégories
Tech

Menu déroulant Flutter avec texte dans la AppBar

Comme je me frotte à Flutter depuis quelques temps, et que je ne dois pas être le seul à peiner parfois, voici quelques petits trucs pense-bête qui pourraient éventuellement servir à d’autres.

Ce que je veux, c’est obtenir un menu déroulant Flutter avec texte dans la AppBar, comme ça :

Menu déroulant Flutter avec texte dans la AppBar

Pour réaliser cela, j’ai besoin visuellement :

  • d’un widget MyAppBar que j’appellerai dans le widget principal
  • d’un texte qui me donne le titre « MonApp »
  • d’un menu déroulant avec un texte
  • et d’un autre menu que je ne traite pas ici.

Ce qui signifie :

  • qu’il faut déclarer un title pour la barre d’application. Ici c’est

title: Text("Mon App", style: TextStyle(fontSize: 20)),

  • que le texte et le bouton doivent être positionné dans un row pour être alignés sur une même ligne ET que ce row est implémenté dans le PopupMenuButton, c’est à dire ce qui permet d’afficher le menu déroulant.
  • et que, puisqu’on a un menu puis un bouton en enfilade, qu’on va coller ça dans une liste actions pour faire propre sur l’interface (et surtout pour y retrouver ses jeunes)

On secoue et ça donne ça :

class MyAppBar extends StatelessWidget implements PreferredSizeWidget {
  // element indispensable pour les AppBar déclarées à part
  Size get preferredSize => new Size.fromHeight(50); // la hauteur du appBar

  @override
  Widget build(BuildContext context) {
    return AppBar(
      backgroundColor: Colors.grey[600],
      title: Text("Mon App", style: TextStyle(fontSize: 20)),
      actions: [
       PopupMenuButton<int>(
            child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
              Text("Le texte du bouton"),
              Icon(Icons.arrow_circle_down),
            ]),
            onSelected: (item)=> onSelected(context, item),
            itemBuilder: (context) => [
                  PopupMenuItem<int>(
                    value: 1,
                    child: Text("Suivi du lien 1"),
                  ),
                  PopupMenuItem<int>(
                    value: 2,
                    child: Text("Suivi du lien 2"),
                  ),
                ]),
        SizedBox(width: 10),
        IconButton(onPressed: () {}, icon: Icon(Icons.menu)),
      ],
    );
  }
}

Vous remarquerez au passage le <int> après les PopupMenuButton et PopupMenuItem. Cela permet de passer en paramètre la valeur du champ déterminée dans value grâce à la méthode onSelected que je vous colle ici.


void onSelected(BuildContext context, int item) {
  switch (item) {
    case 1:
      Navigator.of(context)
          .push(MaterialPageRoute(builder: (context) => MaPage1()));
    case 2:
      Navigator.of(context)
          .push(MaterialPageRoute(builder: (context) => MaPage2()));
  }
}

D’ailleurs, si quelqu’un a une meilleure option, je suis preneur.

Laisser un commentaire