Dans Flutter, puis-je faire des enfants d'un DropdownButton un widget autre que DropdownMenuItem
J'ai une application Web Flutter, qui inclut une vue Web sur certaines pages.
J'utilise PointerInterceptor pour empêcher ma vue Web d'absorber les événements de clic.
Cela fonctionne bien, mais j'ai maintenant une situation où j'ai un DropdownButton
et cliquer dessus crée un tas de DropdownMenuItem
s - je veux envelopper ces éléments dans le même PointerInterceptor
, comme ceci:
DropdownButton<dynamic>(
items: myItems.map((e) => PointerInterceptor( child: DropdownMenuItem(
value: e,
child: Text(e.name),
))).toList(),
Le problème est que cela se traduit par l'erreur suivante:
Le type d'argument 'List' ne peut pas être affecté au type de paramètre 'List<DropdownMenuItem>?'.
Mais j'ai mis mon DropdownButton
dans la barre d'application, et DropdownMenuItems
ils sont injectés dans l'arborescence des widgets directement sous le MaterialApp
widget, il n'y a donc pas de widget de niveau supérieur que je puisse envelopper.
Comment puis-je utiliser le widget PointerInterceptor lorsque le DropdownButton s'attend items
à être DropdownMenuItems ?
Solution du problème
J'ai pu y parvenir en créant une autre classe qui enveloppait le DropdownMenuItems
, puis en l'utilisant comme items
dans le DropdownButton
à sa place.
(c'est-à-dire remplacer DropdownMenuItems
par PointerInterceptedDropdownMenuItem
)
Here is the definition of my wrapper class:
class PointerInterceptedDropdownMenuItem<T> extends DropdownMenuItem {
final VoidCallback? onTap;
final T? value;
final bool enabled;
const PointerInterceptedDropdownMenuItem({
Key? key,
this.onTap,
this.value,
this.enabled = true,
AlignmentGeometry alignment = AlignmentDirectional.centerStart,
required Widget child,
}): super(key: key, alignment:alignment, child: child);
@override Widget build(BuildContext context) {
return PointerInterceptor( child: super.build(context) );
}
}
NB: C'est une bonne solution bien rangée pour la partie de la question demandant que les enfants d'un DropdownButton soient autres qu'un DropdownMenuItem,
mais ce n'est pas une bonne solution pour la partie spécifique de l'emballage des éléments dans le PointerInterceptor classe, et c'est parce qu'avoir autant de PointerInceptors (j'ai une longue liste) a un mauvais impact sur les performances, donc la solution pour cette partie sera de déplacer le PointerInterceptor au niveau supérieur de l'échafaudage, puis de le rendre conditionnel et de mettre à jour un état (reflétant que la liste déroulante est ouverte) pour dire si le PointerInterceptor doit couvrir tout l'écran ou non.
Commentaires
Enregistrer un commentaire