TextField внутри Row вызывает исключение компоновки: невозможно вычислить размер

Я получаю исключение отображения, которое я не понимаю, как исправить. Я пытаюсь создать столбец с тремя строками.

Строка [Изображение]

Строка [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 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, из-за чего он не сможет вычислить размер этой строки?

Ответ 1

(Я предполагаю, что вы используете 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,
            ),
          ),
        ],
      ),

Ответ 2

вы должны использовать Flexible для использования текстового поля внутри строки.

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


              ],//widget
            ),//row

Ответ 3

Принятый ответ, похоже, не устанавливает для меня очень похожую проблему, поэтому, возможно, это еще не все, или я не применяю это решение правильно. Вот код приложения:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

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(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Column(
              children: [
                Expanded(
                  child: Column(
                    children: [
                      new Flexible(
                        child: new TextFormField()
                      )
                    ]
                  )
                )
              ]
            )
          ]
        )
      )
    );
  }
}

У меня есть TextFormField, заключенный в Flexible, но ошибка все еще происходит.

Исключение произошло. BoxConstraints заставляет бесконечную ширину. Эти недопустимые ограничения были предоставлены функции RenderRepaintBoundary layout() следующей функцией, которая, вероятно, вычисляла недопустимые ограничения:
_RenderDecoration._layout.layoutLineBox (пакет: flutter/src/material/input_decorator.dart: 815: 11). Обижающими ограничениями были: BoxConstraints (w = Infinity, 0.0 <= h <= 683.4)

Выход моего врача флаттера выглядит следующим образом:

[flutter] flutter doctor Резюме врача (чтобы увидеть все подробности, запустите flutter doctor -v): [√] Flutter (бета-версия бета-версии, v0.9.4, на Microsoft Windows [версия 10.0.17134.345], локаль en-US) [! ] Android toolchain - разработка для Android-устройств (Android SDK 28.0.3). Статус лицензии на Android X неизвестен. [√] Android Studio (версия 3.1) [√] Подключенные устройства (доступно 1)

! Доктор обнаружил проблемы в 1 категории. код выхода 0

Ответ 4

Простое решение состоит в том, чтобы обернуть Text() внутри Container(). Итак, ваш код будет выглядеть так:

Container(
      child: TextField()
)

Здесь вы также можете получить атрибут width и height контейнера, чтобы настроить внешний вид вашего текстового поля. Не нужно использовать Flexible если вы обертываете свое текстовое поле внутри контейнера.

Ответ 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,
          ),
        ));
  }
}

Ответ 6

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

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

Ответ 7

Вы получаете эту ошибку, потому что 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(),
      ],
    )