325 votes

TextField à l'intérieur de Row provoque une exception de mise en page : Impossible de calculer la taille

Je reçois une exception de rendu que je ne comprends pas comment résoudre. J'essaie de créer une colonne à trois rangées.

Rangée [Image]

Row [TextField]

Rangée [Boutons]

Voici mon code pour construire le conteneur :

Container buildEnterAppContainer(BuildContext context) {
    var container = new Container(
      padding: const EdgeInsets.all(8.0),
      child: new Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          buildImageRow(context),
          buildAppEntryRow(context),
          buildButtonRow(context)
        ],
      ),
    );
    return container;
  }

et mon code buildAppEntryRow pour le conteneur de texte

Widget buildAppEntryRow(BuildContext context) {
    return new Row(
      children: <Widget>[
        new TextField(
          decoration: const InputDecoration(helperText: "Enter App ID"),
          style: Theme.of(context).textTheme.body1,
        )
      ],
    );
  }

Lorsque je l'exécute, j'obtiens l'exception suivante :

I/flutter ( 7674): BoxConstraints forces an infinite width.
I/flutter ( 7674): These invalid constraints were provided to RenderStack's layout() function by the following
I/flutter ( 7674): function, which probably computed the invalid constraints in question:
I/flutter ( 7674):   RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:256:13)
I/flutter ( 7674): The offending constraints were:
I/flutter ( 7674):   BoxConstraints(w=Infinity, 0.0<=h<=Infinity)

Si je change buildAppEntryRow en un simple TextField comme ceci

 Widget buildAppEntryRow2(BuildContext context) {
    return new TextField(
      decoration: const InputDecoration(helperText: "Enter App ID"),
      style: Theme.of(context).textTheme.body1,
    );
  }

Je ne reçois plus l'exception. Qu'est-ce qui m'échappe dans l'implémentation de Row et qui empêche le calcul de la taille de cette ligne ?

0 votes

Voir ceci pour résoudre le problème ci-dessus : stackoverflow.com/a/63698894/10563627

644voto

Collin Jackson Points 29995

(Je suppose que vous utilisez un Row parce que vous voulez mettre d'autres widgets à côté de la TextField à l'avenir).

Le site Row widget veut déterminer la taille intrinsèque de ses enfants non flexibles afin de savoir combien d'espace il lui reste pour les enfants flexibles. Cependant, TextField n'a pas de largeur intrinsèque ; il sait seulement comment s'adapter à la largeur totale de son conteneur parent. Essayez de l'envelopper dans un Flexible ou Expanded pour dire à la Row que vous attendez le TextField pour occuper l'espace restant :

      new Row(
        children: <Widget>[
          new Flexible(
            child: new TextField(
              decoration: const InputDecoration(helperText: "Enter App ID"),
              style: Theme.of(context).textTheme.body1,
            ),
          ),
        ],
      ),

16 votes

Ça ne devrait pas être sur la doc sur le flutter quelque part ?

1 votes

@stt106 c'est --> flutter.io/docs/development/ui/layout/box-constraints Mais je suis d'accord, ce n'est pas facile à trouver. Ils ne rendent pas non plus la solution aussi évidente que Collin Jackson l'a fait ci-dessus.

0 votes

En utilisant cette méthode, on casse mainAxisAlignment pour le widget Row. Avec deux widgets de texte, il n'y a pas de problème, mais avec un widget de texte et un widget de champ de texte contenus dans un champ de texte, il n'y a pas de problème. Flexible il est aligné sur la gauche, sans espacement.

116voto

CopsOnRoad Points 4705

Vous obtenez cette erreur parce que TextField s'étend dans la direction horizontale et il en va de même pour le Row Nous devons donc restreindre la largeur de l'écran de l'utilisateur. TextField il existe de nombreuses façons de le faire.

  1. Utilisez Expanded

     Row(
      children: <Widget>[
        Expanded(child: TextField()),
        OtherWidget(),
      ],
    )
  2. Utilisez Flexible

    Row(
      children: <Widget>[
        Flexible(child: TextField()),
        OtherWidget(),
      ],
    )
  3. Enveloppez-le dans Container ou SizedBox et fournir width

    Row(
      children: <Widget>[
        SizedBox(width: 100, child: TextField()),
        OtherWidget(),
      ],
    )

5 votes

Cette recommandation est très utile. Lorsque vous avez plusieurs TextField en une seule rangée.

0 votes

In Row Flexible est parfait. Expanded a une hauteur fixe et le texte de validation se plante.

15voto

Ajit Paul Points 69

Vous devez utiliser Flexible pour utiliser un champ de texte dans une ligne.

new Row(
              children: <Widget>[
                new Text("hi there"),
                new Container(
                  child:new Flexible(
                        child: new TextField( ),
                            ),//flexible
                ),//container

              ],//widget
            ),//row

1 votes

Je pense que vous n'avez pas besoin de la Container vous pouvez utiliser l'option Flexible directement.

7voto

Shahzad Akram Points 311

Comme @Asif Shiraz l'a mentionné, j'ai eu le même problème et je l'ai résolu en enveloppant la colonne dans un flexible, ici comme ceci,

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        title: 'Flutter Demo',
        theme: new ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: new Scaffold(
          body: Row(
            children: <Widget>[
              Flexible(
                  child: Column(
                children: <Widget>[
                  Container(
                    child: TextField(),
                  )
                  //container
                ],
              ))
            ],
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
          ),
        ));
  }
}

-1voto

vs_lala Points 302

Une solution simple consiste à envelopper votre Text() à l'intérieur d'un Container() . Ainsi, votre code sera comme :

Container(
      child: TextField()
)

Ici, vous disposez également des attributs de largeur et de hauteur d'un conteneur pour ajuster l'apparence de votre champ de texte. Il n'est pas nécessaire d'utiliser Flexible si vous insérez votre champ de texte à l'intérieur d'un conteneur.

2 votes

Ne résout pas la question sans ajouter width: n

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