237 votes

Comment déplacer la feuille de bas de page avec le clavier qui a un champ de texte (autofocused est vrai) ?

J'essaie de créer une feuille de bas de page avec un champ de texte et l'autofocus est réglé sur true pour que le clavier apparaisse. Mais la feuille de bas de page est recouverte par le clavier. Existe-t-il un moyen de déplacer la feuille de fond au-dessus du clavier ?

Padding(
  padding:
      EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
  child: Column(children: <Widget>[
    TextField(
      autofocus: true,
      decoration: InputDecoration(hintText: 'Title'),
    ),
    TextField(
      decoration: InputDecoration(hintText: 'Details!'),
      keyboardType: TextInputType.multiline,
      maxLines: 4,
    ),
    TextField(
      decoration: InputDecoration(hintText: 'Additional details!'),
      keyboardType: TextInputType.multiline,
      maxLines: 4,
    ),]);

1 votes

Il y a également quelques problèmes ouverts sur Github : question principale y un autre avec un commentaire qui propose une solution animée.

1 votes

Pour moi, cela se règle simplement en ajoutant un Padding comme dernier enfant de l'élément Column et définir son remplissage comme padding: MediaQuery.of(context).viewInsets

365voto

Abed Points 447

Ajouter isScrollControlled = true a BottomSheetDialog cela permettra à la feuille inférieure de prendre toute la hauteur requise, ce qui donne plus d'assurance que TextField n'est pas couvert par le clavier.

Ajoutez le rembourrage du clavier en utilisant MediaQuery.of(context).viewInsets.bottom

Note

Si votre BottomSheetModel es Column assurez-vous d'ajouter mainAxisSize: MainAxisSize.min, sinon la feuille couvrira tout l'écran.

Exemple

 showModalBottomSheet(
    shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(25.0))),
    backgroundColor: Colors.black,
    context: context,
    isScrollControlled: true,
    builder: (context) => Padding(
      padding: const EdgeInsets.symmetric(horizontal:18 ),
      child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 12.0),
                child: Text('Enter your address',
                    style: TextStyles.textBody2),
              ),
              SizedBox(
                height: 8.0,
              ),
              Padding(
                padding: EdgeInsets.only(
                    bottom: MediaQuery.of(context).viewInsets.bottom),
                child: TextField(
                  decoration: InputDecoration(
                    hintText: 'adddrss'
                  ),
                  autofocus: true,
                  controller: _newMediaLinkAddressController,
                ),
              ),

              SizedBox(height: 10),
            ],
          ),
    ));

Veuillez noter que :

shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(25.0))),

Ce n'est pas nécessaire. C'est juste que je crée une feuille de fond arrondie.

padding: MediaQuery.of(context).viewInsets

UPDATED Flutter 2.2 casse les changements à nouveau !" Maintenant, vous devez redonner du padding en bas de page pour que le clavier ne chevauche pas la feuille de fond.

3 votes

Après l'application de cette méthode, la feuille inférieure occupait tout l'écran. J'ai contourné le problème en plaçant une valeur statique pour la propriété de hauteur de mon widget Container pour la feuille inférieure.

0 votes

Quel est l'enfant de la feuille inférieure ?

3 votes

@Abed J'ai essayé votre méthode. Est-ce qu'elle ne fonctionne pas pour mon problème merci de vérifier. stackoverflow.com/q/58240592/8822337

192voto

capu Points 87

Ajoute juste :

  • isScrollControlled: true pour montrerModalBottomSheet
  • padding: MediaQuery.of(context).viewInsets au widget dans le constructeur
  • colonne/wrap les deux fonctionnent

    showModalBottomSheet<void>( isScrollControlled: true, context: context, shape: RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(30.0), topRight: Radius.circular(30.0)), ), builder: (BuildContext context) { return Padding( padding: MediaQuery.of(context).viewInsets, child: Container( child: Wrap( children: <Widget>[ TextField( decoration: InputDecoration( border: InputBorder.none, hintText: 'Enter a search term'), ), TextField( decoration: InputDecoration( border: InputBorder.none, hintText: 'Enter a search term'), ), TextField( decoration: InputDecoration( border: InputBorder.none, hintText: 'Enter a search term'), ), TextField( decoration: InputDecoration( border: InputBorder.none, hintText: 'Enter a search term'), ) ], ))); }, );

Mise à jour 25 février 2020 : meilleure solution

showModalBottomSheet(
 isScrollControlled: true,
 builder: (BuildContext context) {

    return SingleChildScrollView(
      child: Container(
        padding:
            EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
        child: Padding(
          padding: const EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 0.0), // content padding
          child: Form(...)) // From with TextField inside

});

3 votes

Juste une note pour tout le monde : Pour la question posée, le widget Wrap n'est pas nécessaire puisque le problème est que la feuille inférieure peut se déplacer au-dessus du clavier et non le contenu de la feuille inférieure elle-même.

0 votes

Cela fonctionne pour moi

42voto

anmol.majhail Points 11892

Afin de se concentrer sur le clavier dans BottomSheet - Enveloppe TextField dans le Widget Padding comme ci-dessous, par exemple Code :

showModalBottomSheet(
              context: context,
              builder: (context) {
                return Container(
                  child: Padding(
                    padding: EdgeInsets.only(
                        bottom: MediaQuery.of(context).viewInsets.bottom),
                    child: TextField(
                      autofocus: true,
                    ),
                  ),
                );
              });

1 votes

Salut Merci. Cela fonctionne pour deux champs enfants mais pas lorsque nous ajoutons un troisième champ. J'ai édité la question avec mon exemple de code.

0 votes

@ManjunathRao Vous devez probablement ajouter "Key" au champ de texte pour les garder uniques afin d'obtenir plus de 2. Faites-moi savoir si cela vous a aidé

0 votes

BottomSheet - a le maxHeight: constraints comme les champs augmentent, la hauteur n'augmentera pas. Vous pouvez utiliser ListView dans BottomSheet pour que les champs soient visibles dans le défilement. Vous pouvez aussi essayer ceci - stackoverflow.com/questions/53311553/

23voto

Robin Points 956

Dans la dernière version de flutter, vous pouvez déplacer votre bottomSheet en utilisant isScrollControlled propriété/paramètre nommé. Supposons que j'ai une fonction (_showModal) qui sera invoquée lorsqu'un bouton est pressé. Et je définis la fonctionnalité de la feuille de fond sur cette fonction.

void _showModal() {
  showModalBottomSheet(
    isScrollControlled: true,
    context: context,
    builder: (BuildContext context) {
      return Column(
        children: <Widget>[
          TextField(// your other code),
          SizedBox(height: 5.0),
          TextField(// your other code),
          SizedBox(height: 5.0),
          TextField(// your other code),
        ]
      );
    },
  );
}

Ici, une ModalBottomSheet apparaîtra mais avec un fullscreen de hauteur. Et vous n'avez pas besoin de cette hauteur. Donc, vous avez besoin de la colonne mainAxisSize a min .

Column(
  mainAxisSize: MainAxisSize.min,
  // your other code
)

Le problème du plein écran en hauteur est résolu, mais ModalBottomSheet ne se déplace pas vers le haut lorsque le clavier apparaît. Ok, pour résoudre ce problème, vous devez définir les paramètres suivants viewInsets le remplissage du fond de votre feuille modale. Pour définir le remplissage, nous devons donc envelopper notre colonne avec Container ou Padding, puis définir le remplissage. Le code final ressemblera à ceci

void _showModal() {
  showModalBottomSheet(
    isScrollControlled: true,
    context: context,
    builder: (BuildContext context) {
      return Container(
        padding: EdgeInsets.only(
          bottom: MediaQuery.of(context).viewInsets.bottom,
        ),
        // You can wrap this Column with Padding of 8.0 for better design
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            TextField(// your other code),
            SizedBox(height: 5.0),
            TextField(// your other code),
            SizedBox(height: 5.0),
            TextField(// your other code),
          ]
        ),
      );
    },
  );
}

J'espère que votre problème est résolu. Merci.

2 votes

Fonctionne comme un charme... !

21voto

Rasel Khan Points 565

Paquet : https://pub.dev/packages/modal_bottom_sheet

Enveloppez votre widget dans Padding et définissez le padding comme suit ==>

padding: MediaQuery.of(context).viewInsets // viewInsets will decorate your screen

Vous pouvez utiliser showMaterialModalBottomSheet ou showModalBottomSheet ou showCupertinoModalBottomSheet

showModalBottomSheet(
        context: context,
        barrierColor: popupBackground,
        isScrollControlled: true, // only work on showModalBottomSheet function
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.only(
                topLeft: Radius.circular(borderRadiusMedium),
                topRight: Radius.circular(borderRadiusMedium))),
        builder: (context) =>  Padding(
            padding: MediaQuery.of(context).viewInsets,
            child: Container(
                   height: 400, //height or you can use Get.width-100 to set height
                   child: <Your Widget here>
             ),)),)

before

after

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