Lorsqu'un PopupMenuButton est enfoncé, la valeur actuellement sélectionnée est mise en surbrillance,
mais quand un DropdownButton est enfoncé , la valeur actuellement sélectionnée n'est pas mise en surbrillance.
Existe-t-il un moyen de mettre en évidence la valeur sélectionnée d'un DropdownButton?
Pour référence, voici quelques exemple de code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: MyHomePage());
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String letter = 'A';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Popup Menu Button')),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 16.0),
Text('PopupMenuButton'),
buildPopupMenuButton(),
SizedBox(height: 16.0),
Text('DropdownButton'),
buildDropdownButton(),
],
),
);
}
Widget buildPopupMenuButton() {
return PopupMenuButton<String>(
padding: EdgeInsets.zero,
initialValue: letter,
onSelected: (val) => setState(() => letter = val),
child: ListTile(
title: Text('The letter $letter'),
),
itemBuilder: (BuildContext context) {
return <PopupMenuItem<String>>[
PopupMenuItem<String>(
value: 'A',
child: Text('The letter A'),
),
PopupMenuItem<String>(
value: 'B',
child: Text('The letter B'),
),
];
},
);
}
Widget buildDropdownButton() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: DropdownButton<String>(
value: letter,
onChanged: (val) => setState(() => letter = val),
items: [
DropdownMenuItem<String>(
value: 'A',
child: Text('The letter A'),
),
DropdownMenuItem<String>(
value: 'B',
child: Text('The letter B'),
),
],
),
);
}
}
Voici une vidéo qui montre le problème:
p>
4 Réponses :
Eh bien, pour autant que je sache, cette superposition grise est un soi-disant «effet d'ondulation» dans la bibliothèque de conception de matériaux. Il semble que Flutter n'adapte pas encore le design complet dans tous les widgets.
Cependant, vous pouvez essayer d'utiliser le widget InkWell pour ajouter ce type d'animations / couleurs aux widgets actuels:
https://flutter.io/docs/cookbook/gestures/ripples
Eg:
PopupMenuItem<String>(
value: 'B',
child: InkWell(child: Text('The letter B'))
),
Je ne sais pas si la largeur sera correcte, mais au moins elle devrait afficher la superposition grise lorsque vous appuyez sur l'entrée .
Vous pouvez également vérifier la source Flutter: https: // com / flutter / flutter / blob / 237fc2fb45639312001e947bf7465ef9f23bb699 / packages / flutter / lib / src / material / popup_menu.dart # L933
Ici, vous pouvez voir que Inkwell est la norme utilisée pour le PopupMenuButton.
Merci pour les commentaires, mais je ne suis pas intéressé par l'effet InkWell lorsque le bouton est enfoncé. Je suis intéressé par l'arrière-plan plus sombre de la valeur actuellement sélectionnée lorsque toutes les valeurs sont affichées.
J'ai également fourni le code source dans ma réponse, vous pourriez essayer de l'imiter un peu car je ne comprends pas vraiment ce que vous voulez vraiment réaliser.
Les éléments de menu déroulant et contextuel sont déjà fournis avec un InkWell, apparemment.
Je recherche également une solution pour changer le focus en fonction de la valeur actuellement sélectionnée. Si vous définissez la valeur initiale, elle reste en surbrillance même après avoir appuyé sur d'autres options. Il ne semble pas y avoir de réponse à cela ici.
Le DropdownMenuItem ne prend pas en charge de nombreuses modifications personnalisées sur l'élément enfant, car il n'y a pas de style, d'arrière-plan, quoi que ce soit dans les attributs DropdownMenuItem pour vous aider. En regardant le code, il n'a vraiment pas été construit pour ça,
Pourtant, il y a quelque chose que vous pourriez ajouter, une simple vérification de l'attribut child de DropdownMenuItem , et enveloppez l'élément enfant Text dans quelque chose d'autre ou stylisez l'élément Text lui-même s'il est coché.
Un exemple:
DropdownMenuItem<String>(
value: 'A',
child: Text('The letter A',
style: TextStyle(
color: letter == 'A' ? Colors.red : Colors.black87,
),
),
)
Notez que dans un scénario réel, vous auriez une méthode avec un paramètre pour construire chaque élément de liste déroulante, donc la vérification n'aurait pas à être codée en dur comme letter == 'A '.
Ce serait le résultat:
Cette approche vous permet de styliser un peu, mais cela a un résultat moche dans certains cas. Bien qu'il soit personnalisable, il y aura toujours une marge blanche autour de l'élément, et il affiche également les mêmes styles lorsque la liste déroulante est fermée, donc cela devient un peu moche sur la page principale.
Au lieu de changer l'arrière-plan, vous pouvez également changer les couleurs du texte, le soulignement, les icônes sur le côté, quelque chose comme ça le rend beaucoup mieux, comme:
Widget buildDropdownButton() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: DropdownButton<String>(
value: letter,
onChanged: (val) => setState(() => letter = val),
items: [
DropdownMenuItem<String>(
value: 'A',
child: Container(
color: letter == 'A' ? Colors.black12 : null,
child: Text('The letter A'),
),
),
DropdownMenuItem<String>(
value: 'B',
child: Container(
color: letter == 'B' ? Colors.black12 : null,
child: Text('The letter B'),
),
),
],
),
);
}
En réponse à votre problème initial qui était: " Je suis intéressé par l'arrière-plan plus sombre de la valeur actuellement sélectionnée lorsque toutes les valeurs sont affichées. "
Votre PopupMenuButton examinera son paramètre initialValue: à chaque fois qu'il est ouvert - l'élément correspondant à cette valeur sera mis en évidence. Vous devrez mettre à jour le paramètre initialValue à chaque fois en utilisant la fonction onSelected .
Assurez-vous que le widget parent est un widget StatefulWidget et créez une référence à quelle que soit votre valeur initiale . Le PopupMenuButton a un paramètre onSelected qui prend une fonction avec le paramètre String .
Chaque fois que vous sélectionnez une option dans le PopupMenuButton , appelez
Class YourClass extends StatefulWidget {
@override
createState() => _YourClassState();
}
class _YourClassState extends State<YourClass> {
...
String initialValue = 'foo';
@override
Widget build(BuildContext context) {
final items = [
PopupMenuItem(
value: 'foo',
child: Text('foo'),
),
PopupMenuItem(
value: 'nice',
child: Text('nice'),
),
}
return Scaffold(
appBar: ...,
drawer: ...,
body: PopupMenuButton(
icon: ...,
itemBuilder: (_) => items,
initialValue: this.initialValue,
onSelected: (value) => bar(value),
),
);
}
void bar(String value) {
setState(() {
...
this.initialValue = value;
});
}
}
La classe complète ressemblera à quelque chose comme ça. p>
setState(() {
...
this.initialValue = value;
});
Le PopupMenuButton fonctionne comme vous le souhaitez. Le problème vient du DropdownButton. La valeur actuelle n'est pas mise en surbrillance lors de l'utilisation d'un DropdownButton.
Vous pouvez envelopper le widget avec Thème pour définir une couleur de surbrillance.
return Theme(
data: ThemeData(highlightColor: Colors.grey[300]),
child: DropdownButton()