295 votes

Lorsque le clavier apparaît, les widgets de Flutter se redimensionnent. Comment éviter cela ?

J'ai une colonne de widgets étendus comme ceci :

 return new Container(
      child: new Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          new Expanded(
            flex: 1,
            child: convertFrom,
          ),
          new Expanded(
            flex: 1,
            child: convertTo,
          ),
          new Expanded(
            flex: 1,
            child: description,
          ),
        ],
      ),
    );

Ça ressemble à ça :

enter image description here

convertFrom comprend un champ de texte. Lorsque je tape sur ce champ de texte, le clavier Android apparaît à l'écran. Cela modifie la taille de l'écran, de sorte que les widgets se redimensionnent comme ceci :

enter image description here

Existe-t-il un moyen de faire en sorte que le clavier "recouvre" l'écran afin que ma colonne ne soit pas redimensionnée ? Si je n'utilise pas Expanded et coder en dur une hauteur pour chaque widget, les widgets ne se redimensionnent pas, mais j'obtiens l'erreur de la bande noire et jaune lorsque le clavier apparaît (parce qu'il n'y a pas assez d'espace). Cette méthode n'est pas non plus flexible pour toutes les tailles d'écran.

Je ne suis pas sûr que ce soit spécifique à Android ou à Flutter.

1 votes

Dans votre corps de Scaffold, utilisez un SingleChildScrollView.

3voto

javeedishaq Points 159

Pour moi, changer la propriété de l'élément ci-dessous de true (vrai) à false (faux).

<item name="android:windowFullscreen">false</item>

dans le fichier

android/app/src/main/res/values/styles.xml

a fait en sorte que Flutter fasse glisser tout le contenu de la page vers le haut lors de la saisie du focus

Flutter drag all page content upwards on input focus

1 votes

Cela ne fonctionnera que pour Android comme il semble...

3voto

aptik Points 355

En fonction du cas d'utilisation, vous pourriez également envisager d'utiliser une aperçu de la liste . Cela permettrait de faire défiler le contenu lorsqu'il n'y a pas assez de place. À titre d'exemple, vous pouvez examiner la page champ de texte Démonstration dans l'application Galerie

5 votes

Mais cela ne rend toujours pas visible le champ de texte que vous avez sélectionné, le clavier le recouvrira toujours. Vous devez le faire défiler vous-même. Je n'en ai pas l'habitude en tant que développeur/utilisateur d'Android

2voto

Pumuckelo Points 75

C'est le parfait solution qui vous donne la possibilité d'avoir un colonne plein écran à l'intérieur d'un SingleChildScrollView . Cela vous permet de créer une mise en page parfaite pour toutes les tailles d'écran + la possibilité de disposer d'un écran défilant qui uniquement défile si vous ouvrez le clavier ou si l'écran déborde après le rendu (par exemple, la validation des champs de saisie de texte)

class PerfectFullScreen extends StatelessWidget {
  const PerfectFullScreen({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
      backgroundColor: Theme.of(context).backgroundColor,
      appBar: AppBar(),
      body: Builder(
        builder: (context) => SingleChildScrollView(
            child: ConstrainedBox(
                constraints: BoxConstraints(
                    minHeight: MediaQuery.of(context).size.height -
                        (MediaQuery.of(context).padding.top + kToolbarHeight)),
                child: IntrinsicHeight(
                    child: Column(
                  children: [
                    Container(
                      height: randomImageHeight,
                      child: Image.asset(
                        "assets/images/change_password.png",
                        fit: BoxFit.cover,
                      ),
                    ),
                    Expanded(
                        child: WidgetThatShouldTakeRemainingSpace() )
                  ],
                )))),
      ),
    ));
  }
}

La partie importante est le Boîte à contraintes avec le bon Contraintes de la boîte et le InstrinsicHeight Widget.

PS : (MediaQuery.of(context).padding.top + kToolbarHeight) == Hauteur de l'Appbar

1 votes

De la docs de IntrinsicHeight (c'est moi qui souligne) : "Cette classe est relativement coûteuse, car elle ajoute une passe de mise en page spéculative avant la phase de mise en page finale. Évitez de l'utiliser dans la mesure du possible. Dans le pire des cas, ce widget peut aboutir à une disposition qui est O(N²) dans la profondeur de l'arbre". Annoncer qu'il est parfait en utilisant un widget qu'il est recommandé d'éviter si possible, car il existe de nombreuses alternatives, peut être un peu trompeur.

-2voto

Rudr Thakur Points 74

J'étais confronté au même problème et j'ai commencé à essayer des solutions aléatoires pour le résoudre et soudain, ceci a réglé le problème. enter image description here

Enveloppez le conteneur parent principal dans un SingleChildScrollView() et donnez-lui la hauteur du périphérique, c'est-à-dire device_height = MediaQuery.of(context).size.height.

Cela permet de faire défiler toute la page mais ne redimensionne aucun widget.

6 votes

Il est déconseillé de publier des captures d'écran du code, car cela ne permet pas aux membres de le copier et de le manipuler facilement eux-mêmes.

0 votes

Hé, j'étais nouveau sur stackoverflow à l'époque et je ne savais pas comment ajouter du code à votre réponse. J'aurais édité la réponse plus tard, mais je n'ai plus le code.

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