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

#flutter #dart

#flutter #dart

Вопрос:

Я сделал очень простой виджет для переключения между 2 вариантами:

 import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home:  DoubleChoiceTextWidget(
              choiceText1: "A",
              choiceText2: "B",
              choice1: Container(child: Column(children:[Text("test"), Spacer(),Text("test2")])),
              choice2: Container(),
            )
    );
  }
}


class DoubleChoiceTextWidget extends StatefulWidget {
  DoubleChoiceTextWidget(
      {Key key,
      this.choiceText1,
      this.choiceText2,
      @required this.choice1,
      @required this.choice2,})
      : super(key: key);
  int selected = 0;
  final String choiceText1;
  final String choiceText2;
  final Widget choice1;
  final Widget choice2;

  @override
  _DoubleChoiceTextWidgetSate createState() => _DoubleChoiceTextWidgetSate();
}

class _DoubleChoiceTextWidgetSate extends State<DoubleChoiceTextWidget> {
  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.only(bottom: 5),
      child:
      Column(children: [
        Row(
            children: [
              Container(
                  child: GestureDetector(
                      onTap: () => setState(() {
                            widget.selected = 0;
                          }),
                      child: Text(widget.choiceText1,))),
              Container(
                  child: GestureDetector(
                      onTap: () => setState(() {
                            widget.selected = 1;
                          }),
                      child: Text(widget.choiceText2,)))
            ]),
        widget.selected == 0 ? widget.choice1 : widget.choice2
      ]),
    );
  }
}
 

Проблема в том, что когда я добавляю Spacer() то, что вы видите выше, я получаю

 RenderFlex children have non-zero flex but incoming height constraints are unbounded.
 

Если вы просто удалите Spacer() сверху, все работает.

Я не знаю, почему я получаю эту ошибку, поскольку нет элементов, которые пытаются расширяться вечно, как Expand или Flexible как родительский элемент Column(children:[Text("test"), Spacer(),Text("test2")])

Как я могу это исправить, не задавая ему фиксированную высоту?

Комментарии:

1. Spacer это как Expanded без дочернего элемента.

Ответ №1:

Вы можете скопировать вставить выполнить полный код ниже
, чтобы исправить это, вы можете choice1 использовать Expanded

 choice1: Expanded(
            child: Container(
                child:
                    Column(children: [Text("test"), Spacer(), Text("test2")])),
          ),
 

рабочая демонстрация

введите описание изображения здесь

полный код

 import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: SafeArea(
      child: Scaffold(
        body: DoubleChoiceTextWidget(
          choiceText1: "A",
          choiceText2: "B",
          choice1: Expanded(
            child: Container(
                child:
                    Column(children: [Text("test"), Spacer(), Text("test2")])),
          ),
          choice2: Container(),
        ),
      ),
    ));
  }
}

class DoubleChoiceTextWidget extends StatefulWidget {
  DoubleChoiceTextWidget({
    Key key,
    this.choiceText1,
    this.choiceText2,
    @required this.choice1,
    @required this.choice2,
  }) : super(key: key);
  int selected = 0;
  final String choiceText1;
  final String choiceText2;
  final Widget choice1;
  final Widget choice2;

  @override
  _DoubleChoiceTextWidgetSate createState() => _DoubleChoiceTextWidgetSate();
}

class _DoubleChoiceTextWidgetSate extends State<DoubleChoiceTextWidget> {
  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.only(bottom: 5),
      child: Column(children: [
        Row(children: [
          Container(
              child: GestureDetector(
                  onTap: () => setState(() {
                        widget.selected = 0;
                      }),
                  child: Text(
                    widget.choiceText1,
                  ))),
          Container(
              child: GestureDetector(
                  onTap: () => setState(() {
                        widget.selected = 1;
                      }),
                  child: Text(
                    widget.choiceText2,
                  )))
        ]),
        widget.selected == 0 ? widget.choice1 : widget.choice2
      ]),
    );
  }
}
 

Комментарии:

1. В вашем случае вам нужно развернуть столбец _DoubleChoiceTextWidgetSate, чтобы сообщить системе занять все доступное пространство после строки.