TextField всередині рядка викликає виключення макета: Неможливо обчислити розмір


147

Я отримую виняток візуалізації, який я не розумію, як виправити. Я намагаюся створити стовпчик, який має 3 ряди.

Рядок [Зображення]

Рядок [TextField]

Рядок [кнопки]

Ось мій код для складання контейнера:

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;
  }

і мій buildAppEntryRow код текстового контейнера

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

Під час запуску я отримую таке виняток:

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)

Якщо я зміню buildAppEntryRow на просто TextField замість цього

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

Я вже не отримую винятку. Що мені не вистачає з реалізацією Row, через яку вона не може обчислити розмір цього рядка?

Відповіді:


318

(Я припускаю, що ви використовуєте, Rowоскільки TextFieldв майбутньому ви хочете розмістити інші віджети .)

RowВіджет хоче визначити характеристическую розмір його негнучких дітей , так що знає , як багато місця , що він залишив для гнучких з них. Однак TextFieldне має внутрішньої ширини; він знає лише, як розмістити себе на повну ширину батьківського контейнера. Спробуйте загорнути його в Flexibleабо Expandedсказати, Rowщо ви очікуєте, що TextFieldзайме місце, що залишилося:

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

3
Хіба це не повинно бути десь на плавучому доку?
stt106

1
@ stt106 це -> flutter.io/docs/development/ui/layout/box-constraints Але я згоден, це знайти не просто. Вони також не роблять рішення настільки очевидним, як це робив Колін Джексон вище.
Реп

За допомогою цього методу перерви mainAxisAlignmentдля віджета Row. З двома текстовими віджетами немає жодної проблеми, однак із текстовим віджетом та віджетом Textfield, що містяться в Flexibleньому, вирівнюється ліворуч без пробілів.
Hasen

Чи можу я попросити вас поглянути на питання, пов'язане з Flutter тут: stackoverflow.com/questions/60565658/… ?
Істіаке Ахмед

30

Ви отримуєте цю помилку через те, що вона TextFieldрозширюється в горизонтальному напрямку, і це робить так Row, тому нам потрібно обмежувати ширину TextField, існує багато способів зробити це.

  1. Використовуйте Expanded

     Row(
      children: <Widget>[
        Expanded(child: TextField()),
        OtherWidget(),
      ],
    )
  2. Використовуйте Flexible

    Row(
      children: <Widget>[
        Flexible(child: TextField()),
        OtherWidget(),
      ],
    )
  3. Загорніть його Containerабо SizedBoxнадайтеwidth

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

2
Ця рекомендація настільки корисна. Коли у вас є кілька TextFieldв одному ряду.
Бен

11

ви повинні використовувати гнучкий, щоб використовувати текстове поле всередині рядка.

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


              ],//widget
            ),//row

Я думаю, що вам це не потрібно Container, ви можете використовувати Flexibleбезпосередньо.
Феліпе Аугусто

6

Рішення полягає в тому, щоб загорнути Text()всередину один із наступних віджетів: Expandedабо Flexible. Отже, ваш код із використанням розширеного виглядатиме так:

Expanded(
           child: TextField(
             decoration: InputDecoration(
               hintText: "Demo Text",
               hintStyle: TextStyle(fontWeight: FontWeight.w300, color: Colors.red)
              ),
           ),
        ),

5

Як згадував @Asif Shiraz, у мене була така ж проблема, і я вирішив це, обернувши стовпчик у гнучку, ось так,

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,
          ),
        ));
  }
}

0

Просте рішення - загорнути Text()всередину Container(). Отже, ваш код буде таким:

Container(
      child: TextField()
)

Тут ви також отримуєте атрибут ширини та висоти контейнера для налаштування зовнішнього вигляду вашого текстового поля. Не потрібно використовувати, Flexibleякщо ви загортаєте текстове поле всередині контейнера.


1
не вирішує питання, не додаючиwidth: n
user3249027
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.