将Renderbox添加到行中时未进行布局

时间:2019-06-04 03:54:10

标签: flutter dart flutter-layout

我已经看过很多有关此错误的答案,而且我不确定是哪个小部件宽度引起的。理想情况下,我希望可以滚动并可以轻松管理的垂直表单。我的表单可以按我的意愿工作,但是随着我添加更多字段,我将需要滚动。在为此做准备的过程中,我还想了一下,决定将标签和字段制作为水平表单元素。在添加“字段”方法之前,我有一个标签小部件和一个文本框小部件,它们直接放入表单中,但是我决定将这两个小部件包装成一行,以节省一些屏幕空间。我曾尝试将它们包装在一个大小合适的盒子中,因为错误表明这是小部件尺寸的不确定性。

有人可以帮我吗?另外,是否有任何资源可以解释如何更好地解决此类小部件问题?那里有没有资源讨论我面临的问题?

预先感谢

import 'package:flutter/material.dart';
import 'package:wedding_app/models/constants/colors.dart';
import 'package:wedding_app/models/constants/styles.dart';
import 'package:wedding_app/models/constants/utility.dart';
import 'package:intl/intl.dart';

class BudgetWidget extends StatefulWidget {
  @override
  _BudgetWidgetState createState() => _BudgetWidgetState();
}
// limo, flowers, wedding invites, save the dates, center pieces,

class _BudgetWidgetState extends State<BudgetWidget> {
  _BudgetWidgetState({this.totalBudget});

  var currencyFormat = NumberFormat.simpleCurrency();

  double totalBudget = 0;
  double currentExpenses = 0;
  Map<String, double> expenses =
      new Map.from({"venue": 0.0, "limo": 0.0, "flowers": 0.0});

  @override
  Widget build(BuildContext context) {
    final colors = ApplicationColors();

    var form = <Widget>[
      Padding(
        padding: EdgeInsets.only(top: BudgetingStyles.topPadding(context)),
        child: Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Center(
              child: Text(
                totalBudget == null || totalBudget == 0
                    ? "Your Budget"
                    : currencyFormat.format(
                        totalBudget - expenses.values.reduce((a, b) => a + b)),
                style: TextStyle(
                    fontFamily: "acme",
                    fontSize: BudgetingStyles.headerFontSize(context),
                    color: colors.black),
              ),
            ),
          ],
        ),
      ),
      textBox(
        "Enter your budget",
        BudgetingStyles.textBoxMargins(context),
        BudgetingStyles.topPadding(context),
        (String value) {
          if (Utility.isNumeric(value)) {
            setState(() {
              totalBudget = double.parse(value);
            });
          } else if (totalBudget > 0 && value.length == 0) {
            setState(() {
              totalBudget = 0;
            });
          }
        },
      ),
      Padding(
        padding: EdgeInsets.only(top: BudgetingStyles.topPadding(context) * 2),
        child: Text(
          "Expenses",
          style: TextStyle(
              fontFamily: "acme",
              fontSize: BudgetingStyles.headerFontSize(context)),
        ),
      ),
      Padding(
        padding: EdgeInsets.only(top: 3),
        child: Divider(
          color: colors.black,
        ),
      ),
      field("Venue Cost", "Venue", "venue"),
      field("Limo Cost", "Limo", "limo"),
      field("Flowers Cost", "Flowers", "flowers")
    ];

    var innerContainer = Container(
      color: colors.ivory,
      child: Column(
        mainAxisSize: MainAxisSize.max,
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.start,
        children: form,
      ),
    );

    return Scaffold(
      body: innerContainer,
    );
  }

// Why did wrapping it the label and field in a row, give a paint error
  Widget field(String hintText, String labelText, String expenseKey) {
    return Row(
      mainAxisSize: MainAxisSize.max,
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        Container(
          child: Padding(
            padding: const EdgeInsets.only(top: 2.0),
            child: Text(
              labelText,
              style: TextStyle(
                  fontFamily: "acme",
                  fontSize: BudgetingStyles.subHeaderFontSize(context)),
            ),
          ),
        ),
        textBox(
          hintText,
          BudgetingStyles.textBoxMargins(context),
          BudgetingStyles.topPadding(context),
          (String value) {
            setState(
              () {
                expenses[expenseKey] =
                    Utility.isNumeric(value) ? double.parse(value) : 0;
              },
            );
          },
        )
      ],
    );
  }

  Widget textBox(String hintText, double textboxPaddingWidth, double topPadding,
      void onChangeHandler(String value)) {
    return Container(
      child: Padding(
        padding: EdgeInsets.only(
            left: textboxPaddingWidth,
            right: textboxPaddingWidth,
            top: topPadding),
        child: TextField(
            textAlign: TextAlign.center,
            keyboardType: TextInputType.number,
            decoration: InputDecoration(
              hintText: hintText,
            ),
            onChanged: onChangeHandler),
      ),
    );
  }
}

这是我能找到的最接近堆栈跟踪的东西

The following RenderObject was being processed when the exception was fired:
I/flutter (16757):   RenderFlex#a932f relayoutBoundary=up3 NEEDS-LAYOUT NEEDS-PAINT
I/flutter (16757):   creator: Row ← Column ← DecoratedBox ← Container ← MediaQuery ← LayoutId-[<_ScaffoldSlot.body>] ←
I/flutter (16757):   CustomMultiChildLayout ← AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ←
I/flutter (16757):   _InkFeatures-[GlobalKey#bfdef ink renderer] ← NotificationListener<LayoutChangedNotification> ← ⋯
I/flutter (16757):   parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size)
I/flutter (16757):   constraints: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=Infinity)
I/flutter (16757):   size: MISSING
I/flutter (16757):   direction: horizontal
I/flutter (16757):   mainAxisAlignment: center
I/flutter (16757):   mainAxisSize: max
I/flutter (16757):   crossAxisAlignment: stretch
I/flutter (16757):   textDirection: ltr
I/flutter (16757):   verticalDirection: down
I/flutter (16757): This RenderObject had the following descendants (showing up to depth 5):
I/flutter (16757):   RenderPadding#b1255 NEEDS-LAYOUT NEEDS-PAINT
I/flutter (16757):     RenderParagraph#411ca NEEDS-LAYOUT NEEDS-PAINT
I/flutter (16757):   RenderPadding#45b3e NEEDS-LAYOUT NEEDS-PAINT
I/flutter (16757):     RenderSemanticsAnnotations#4c0e1 NEEDS-LAYOUT NEEDS-PAINT
I/flutter (16757):       RenderIgnorePointer#2e796 NEEDS-LAYOUT NEEDS-PAINT
I/flutter (16757):         RenderPointerListener#d6273 NEEDS-LAYOUT NEEDS-PAINT
I/flutter (16757):           _RenderDecoration#df698 NEEDS-LAYOUT NEEDS-PAINT
I/flutter (16757): ════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter (16757): Another exception was thrown: RenderBox was not laid out: RenderFlex#a932f relayoutBoundary=up3 NEEDS-PAINT
I/flutter (16757): Another exception was thrown: RenderBox was not laid out: RenderFlex#edb16 relayoutBoundary=up2 NEEDS-PAINT
I/flutter (16757): Another exception was thrown: RenderBox was not laid out: RenderDecoratedBox#ca6a1 relayoutBoundary=up1 NEEDS-PAINT
I/flutter (16757): Another exception was thrown: RenderBox was not laid out: RenderDecoratedBox#ca6a1 relayoutBoundary=up1

1 个答案:

答案 0 :(得分:2)

请尝试通过以下

替换字段小部件代码
    Widget field(String hintText, String labelText, String expenseKey) {
    return Expanded(
      child: Row(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          Container(
            child: Padding(
              padding: const EdgeInsets.only(top: 2.0),
              child: Text(
                labelText,
                style: TextStyle(
                    fontFamily: "acme",
                    fontSize: BudgetingStyles.subHeaderFontSize(context)),
              ),
            ),
          ),
          Expanded(
            child: textBox(
              hintText,
              BudgetingStyles.textBoxMargins(context),
              BudgetingStyles.topPadding(context),
                  (String value) {
                setState(
                      () {
                    expenses[expenseKey] =
                    Utility.isNumeric(value) ? double.parse(value) : 0;
                  },
                );
              },
            ),
          )
        ],
      ),
    );
  }

据我可以从您的代码中进行研究,您需要将RowtextBox都用Expanded包装,因此两个小部件都遵守约束。