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 DropdownButtonet cliquer dessus crée un tas de DropdownMenuItems - 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 DropdownButtondans la barre d'application, et DropdownMenuItemsils sont injectés dans l'arborescence des widgets directement sous le MaterialAppwidget, 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 itemsdans le DropdownButtonà sa place.
(c'est-à-dire remplacer DropdownMenuItemspar 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

Posts les plus consultés de ce blog

Erreur Symfony : "Une exception a été levée lors du rendu d'un modèle"

Détecter les appuis sur les touches fléchées en JavaScript

Une chaîne vide donne "Des erreurs ont été détectées dans les arguments de la ligne de commande, veuillez vous assurer que tous les arguments sont correctement définis"