163 votes

Comment masquer le clavier d'entrée souple sur Flutter après avoir cliqué en dehors du TextField/n'importe où sur l'écran ?

Actuellement, je connais la méthode pour masquer le clavier virtuel en utilisant ce code, par les méthodes onTap de n'importe quel widget.

FocusScope.of(context).requestFocus(new FocusNode());

Mais je veux masquer le clavier virtuel en cliquant en dehors du TextField ou n'importe où sur l'écran. Y a-t-il une méthode en flutter pour faire cela?

3 votes

Vous pouvez envelopper tout votre écran dans un docs.flutter.io/flutter/widgets/GestureDetector-class.html et appeler le code ci-dessus dans onTap: () => FocusScope.of(context).requestFocus(new FocusNode());

1 votes

Merci @GünterZöchbauer. Y a-t-il une méthode d'événement tactile, car appuyer sur l'écran ne va pas résoudre mon problème. Le clavier se cache lors de la méthode onTap. J'ai besoin de masquer le clavier fréquemment lorsque je touche l'écran.

0 votes

Désolé, je ne suis pas. Pourquoi taper ne résoudrait-il pas votre problème? Vous appuyez sur l'arrière-plan ou similaire. Lorsque cela se produit, vous appelez ... requestFocus ...

314voto

Daizy Arora Points 486

Vous le faites d'une mauvaise manière, essayez simplement cette méthode simple pour masquer le clavier virtuel. Vous devez simplement envelopper tout votre écran dans la méthode GestureDetector et dans la méthode onTap écrire ce code.

        FocusScope.of(context).requestFocus(new FocusNode());

Voici un exemple complet:

new Scaffold(

body: new GestureDetector(
  onTap: () {

    FocusScope.of(context).requestFocus(new FocusNode());
  },
child: new Container(
   //reste de votre code écrit ici
    )
 )

Mis à jour (mai 2021)

return GestureDetector(
      onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
      child: Scaffold(
        appBar: AppBar(
          title: Text('Login'),
        ),
        body: Body(),
      ),
    );

Cela fonctionnera même lorsque vous touchez la AppBar, new est optionnel en Dart 2. FocusManager.instance.primaryFocus renverra le nœud qui a actuellement le focus principal dans l'arborescence des widgets.

Accès conditionnel en Dart avec la null-safety

17 votes

En fait, seulement avec un paramètre behavior: HitTestBehavior.translucent,, onTap est toujours appelé. Cela n'a pas fonctionné pour moi sur certains taps sans ce paramètre.

6 votes

Cette réponse est obsolète. Veuillez consulter la réponse mise à jour pour la v1.17.1 (au moins :)) ici stackoverflow.com/a/61986983/705842

1 votes

Parfois, le détecteur de gestes ne fonctionne pas sur toute l'écran, puis enveloppe simplement l'échafaudage à l'intérieur du widget GestureDetector.

46voto

George Points 1814

Updated

À partir de mai 2019, FocusNode dispose désormais de la méthode unfocus :

Annule toutes les demandes de mise au premier plan en attente.

Cette méthode est sûre à appeler peu importe si ce noeud a déjà demandé le focus.

Utilisez unfocus si vous avez déclaré un FocusNode pour vos champs de texte :

final focusNode = FocusNode();

// ...

focusNode.unfocus();

Ma réponse originale suggérait d'utiliser la méthode detach - utilisez-la uniquement si vous devez vous débarrasser complètement de votre FocusNode. Si vous prévoyez de le conserver - utilisez plutôt unfocus.

Si vous n'avez pas spécifiquement déclaré un FocusNode - utilisez unfocus pour le FocusScope de votre contexte actuel :

FocusScope.of(context).unfocus();

Voir l'historique des révisions pour la réponse originale.

0 votes

detach n'est plus disponible, je crois. J'ai essayé de l'appeler, mais cela ne fonctionne pas - il dit qu'il n'y a pas de fonction avec ce nom.

0 votes

@RodrigoVieira merci de l'avoir souligné. J'ai supprimé les informations périmées de mon message.

29voto

Enveloppez tout l'écran dans GestureDetector comme

new Scaffold(

  body: new GestureDetector(
      onTap: () {
        // appeler cette méthode ici pour masquer le clavier virtuel
        FocusScope.of(context).requestFocus(new FocusNode());
      },
    child: new Container(
       -
       -
       -
        )
   )

0 votes

Juste pour rappel : Créer des FocusNode à la demande sans les disposer risque de provoquer des fuites de mémoire...

24voto

atereshkov Points 448

J'ai ajouté cette ligne

behavior: HitTestBehavior.opaque,

au GestureDetector et il semble maintenant fonctionner comme prévu.

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context).calculatorAdvancedStageTitle),
      ),
      body: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTap: () {
          FocusScope.of(context).requestFocus(new FocusNode());
        },
        child: Padding(
          padding: const EdgeInsets.only(
            left: 14,
            top: 8,
            right: 14,
            bottom: 8,
          ),
          child: Text('Travail'),
        ),
      )
    );
  }

1 votes

D'une certaine manière, le hittestbehaviour est nécessaire pour que cela fonctionne sur iOS.

20voto

omnesia Points 870

Juste une petite remarque:

Si vous utilisez ListView, sa propriété keyboardDismissBehavior pourrait vous intéresser :

ListView(
  keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
  children: [],
)

4 votes

Votre petit mot de côté est grand!

0 votes

Merci ! note impressionnante. Solution parfaite pour Searchdelegate.

0 votes

Merci, cela fonctionne également pour GridView.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X