Flutter RenderBox 没有布局

Posted

技术标签:

【中文标题】Flutter RenderBox 没有布局【英文标题】:Flutter RenderBox was not laid out 【发布时间】:2021-11-07 12:21:20 【问题描述】:

所以我正在尝试制作一个简单的应用程序,我可以在其中进行交易。我正试图在专栏上展示它们。当我在没有调试的情况下进行开发时,它没有给我任何错误。但是当我尝试调试时,它给了我这些错误。我检查了 *** 上的其他问题和答案并尝试了它们,但它们都没有奏效。

这是错误

════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderFlex#f47be relayoutBoundary=up1 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1930 pos 12: 'hasSize'

The relevant error-causing widget was
Scaffold
lib\main.dart:32
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderPhysicalShape#d73e6 relayoutBoundary=up8
...........

等等。

这是我的代码main.dart

import 'package:flutter/material.dart';

import 'custom_text.dart';
import 'transaction_model.dart';
import 'transaction.dart';

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

class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Expense App',
      theme: ThemeData(primaryColor: Colors.indigo.shade400),
      darkTheme: ThemeData.dark(),
      home: MyHomePage(),
    );
  


class MyHomePage extends StatelessWidget 
  final List<TransactionModel> transactionItems = [
    TransactionModel(1, "M1 Macbook Pro", 1299, DateTime.now()),
    TransactionModel(2, "Rampage SMR-X 17", 15.75, DateTime.now()),
    TransactionModel(3, "Xiaomi Redmi Note 8 Pro", 299.99,
        DateTime.fromMicrosecondsSinceEpoch(DateTime.now().millisecond + 20000))
  ];

  @override
  Widget build(BuildContext context) 
    return Scaffold(
        appBar: AppBar(title: Text("Expense App")),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Container(
                width: double.infinity,
                height: 128,
                child: Card(
                  color: Colors.indigo.shade300,
                  child: CustomText("Chart", EdgeInsets.all(8), Colors.white,
                      24, FontWeight.bold),
                  elevation: 8,
                )),
            Container(
              margin: EdgeInsets.fromLTRB(0, 8, 0, 0),
              child: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: transactionItems.map((item) 
                    return Transaction(item);
                  ).toList()),
            )
          ],
        ));
  

这是transaction.dart

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

import 'custom_text.dart';
import 'transaction_model.dart';

class Transaction extends StatelessWidget 
  final TransactionModel item;

  Transaction(this.item);

  final DateFormat dateFormat = DateFormat("MMMM d yyyy");

  @override
  Widget build(BuildContext context) 
    return Container(
      margin: EdgeInsets.all(4),
      width: double.infinity,
      child: Card(
        elevation: 8,
        shadowColor: Colors.indigo.shade200.withOpacity(0.6),
        color: Colors.grey.shade100,
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Container(
                width: 64,
                height: double.infinity,
                alignment: Alignment.center,
                margin: EdgeInsets.all(8),
                decoration: BoxDecoration(
                    border: Border.all(color: Colors.indigo.shade900, width: 1),
                    borderRadius: BorderRadius.all(Radius.circular(4))),
                child: CustomText(item.amount.toString(), EdgeInsets.all(4),
                    Colors.indigo.shade900, 16, FontWeight.normal)),
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                CustomText(
                    item.title.toString(),
                    EdgeInsets.fromLTRB(4, 8, 4, 4),
                    Colors.indigo.shade400,
                    16,
                    FontWeight.bold),
                CustomText(
                    dateFormat.format(item.date),
                    EdgeInsets.fromLTRB(4, 8, 4, 4),
                    Colors.indigo.shade500,
                    16,
                    FontWeight.w400),
              ],
            )
          ],
        ),
      ),
    );
  

应用截图

感谢您的帮助!

【问题讨论】:

如果你包含TransactionModel将会很有帮助。 【参考方案1】:

我通过将 height 参数添加到我的 Transaction 小部件来解决问题。

...

class Transaction extends StatelessWidget 
  final TransactionModel item;

  Transaction(this.item);

  final DateFormat dateFormat = DateFormat("MMMM d yyyy");

  @override
  Widget build(BuildContext context) 
    return Container(
      margin: EdgeInsets.all(4),
      width: double.infinity,
      height: 72,
...

【讨论】:

【参考方案2】:

你必须指定包裹列的容器高度

改变这个

Container(
          margin: EdgeInsets.fromLTRB(0, 8, 0, 0),
          child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: transactionItems.map((item) 
                return Transaction(item);
              ).toList()),
        )

到这里

Container( height: 200,
          margin: EdgeInsets.fromLTRB(0, 8, 0, 0),
          child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: transactionItems.map((item) 
                return Transaction(item);
              ).toList()),
        )

建议: 您应该使用 ListView.builder,而不是该容器内的列

使用列表视图:

  Container( height: 200,
          margin: EdgeInsets.fromLTRB(0, 8, 0, 0),
          child: ListView.builder(
              itemCount: transactionItems.length,
              builder: (BuildContext ctx, int index)
                return Transaction(transactionItems[index]);
                ),
        )

另外,请参考这些答案Flutter: RenderBox was not laid out

【讨论】:

感谢您的回答。我尝试了 200 和 double.infinity 作为高度,但没有一个起作用。

以上是关于Flutter RenderBox 没有布局的主要内容,如果未能解决你的问题,请参考以下文章

Flutter原理—布局绘制

Flutter原理—布局绘制

Flutter原理—布局绘制

Flutter的布局

Flutter:RenderBox 未布置:RenderRepaintBoundary#58c65 relayoutBoundary=up1 NEEDS-PAINT

溢出框 RenderBox 未布局:RenderRepaintBoundary#7796e 需要-布局需要-油漆