【问题标题】:How to lay out Rows and Columns in Flutter widget如何在 Flutter 小部件中布局行和列
【发布时间】:2022-01-01 17:32:58
【问题描述】:

我正在尝试为带有一些文本和文本框的简单屏幕构建 UI,但我遇到了类似这样的奇怪布局错误。

Error: Cannot hit test a render box that has never been laid out.
The hitTest() method was called on this RenderBox: RenderStack#487f4 NEEDS-LAYOUT NEEDS-PAINT:
  creator: Stack ← _FloatingActionButtonTransition ← MediaQuery ← LayoutId-[<_ScaffoldSlot.floatingActionButton>] ← CustomMultiChildLayout ← AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ← _InkFeatures-[GlobalKey#0cc7b ink renderer] ← NotificationListener<LayoutChangedNotification> ← PhysicalModel ← AnimatedPhysicalModel ← ⋯
  parentData: offset=Offset(0.0, 0.0); id=_ScaffoldSlot.floatingActionButton
  constraints: MISSING
  size: MISSING
  alignment: Alignment.centerRight
  textDirection: ltr
  fit: loose
Unfortunately, this object's geometry is not known at this time, probably because it has never been laid out. This means it cannot be accurately hit-tested.
If you are trying to perform a hit test during the layout phase itself, make sure you only hit test nodes that have completed layout (e.g. the node's children, after their layout() method has been called).
    at Object.throw_ [as throw] (http://localhost:61969/dart_sdk.js:5061:11)
    at http://localhost:61969/packages/flutter/src/rendering/layer.dart.lib.js:4204:23
    at stack.RenderStack.new.hitTest (http://localhost:61969/packages/flutter/src/rendering/layer.dart.lib.js:4209:26)
    at http://localhost:61969/packages/flutter/src/rendering/layer.dart.lib.js:7665:44
    at box.BoxHitTestResult.wrap.addWithPaintOffset (http://localhost:61969/packages/flutter/src/rendering/layer.dart.lib.js:7418:19)
...

所以,我删除了所有代码,只保留了两个文本框和两个文本字段,以了解导致问题的原因。但我仍然无法弄清楚原因。这是我的无状态小部件的构建方法的简化代码:

@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
    appBar: AppBar(
      backgroundColor: Colors.red,
      title: Text("Create"),
    ),
    body: Container(
        child:Column(
            children: [
              //First row - Amount and Ccy labels/text boxes
              Expanded(
                  child: Row(
                    children: [
                      Expanded(
                          child:Column(
                            mainAxisSize: MainAxisSize.max,
                            children: [
                              Text('Amount'),
                              TextField(),
                            ],
                          )
                      ),
                      Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Text('Currency'),
                          TextField(),
                        ],
                      )
                    ],
                  )
              ),
              //Second Row - Comment label/text box
            ]
        )
    )
);

}

我想知道我在这里是否缺少一些基本概念。我正在 Chrome 上测试它。

【问题讨论】:

    标签: flutter flutter-layout flutter-web


    【解决方案1】:

    如果您在 SizedBox 中使用具有确定高度的 TextField,它可能会起作用

    【讨论】:

    • 但是为什么它不能按原样工作??
    【解决方案2】:

    输入代码后我没有这个问题。这个 UI 是你想要实现的吗?

    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            title: "title",
            theme: ThemeData(primarySwatch: Colors.green),
            home: Scaffold(
              appBar: AppBar(
                backgroundColor: Colors.red,
                title: const Text("Create"),
              ),
              body: Container(
                  child: Column(children: [
                //First row - Amount and Ccy labels/text boxes
    
                Row(children: [
                  Expanded(
                      child: Column(
                    mainAxisSize: MainAxisSize.max,
                    children: const [
                      Text('Amount'),
                      TextField(),
                    ],
                  )),
                  Column(
                    mainAxisSize: MainAxisSize.min,
                    children: const [
                      Text('Currency'),
                   
                    ],
                  )
                  //Second Row - Comment label/text box
                ])
              ])),
            ));
      }
    }
    

    【讨论】:

    • 是的,就是这样,但它不起作用!如果我注释掉第二列,它会起作用。添加回来,给出相同的堆栈跟踪。请在 chrome 上运行它。不在 AVD 中。
    • 现在试试,我刚刚从第二列中删除了 TextField(),它可以在 chrome 上运行,奇怪的问题
    【解决方案3】:

    我想我找到了问题的答案。当我将两个文本字段放在一行中时,第一个在 Expanded 小部件中时,颤动无法计算为第二个分配的正确宽度,因为 TextField 与 Text 不同,它们自己没有任何宽度。 因此,它的父级必须提供一个宽度,否则颤动必须知道将它赋予该 TextField 的宽度。当我将两个文本字段都放在各自的 Expanded 中并为每个字段分配一个 flex 值时,它工作正常。像这样:

    Expanded(
      flex:3, //this column is thrice as wide as the second one
      child: Column(
        mainAxisSize: MainAxisSize.max,
        children: const [
          Text('Amount'),
          TextField(),
        ],
      )),
    
    Expanded(
        flex: 1, 
        child:Column(
        mainAxisSize: MainAxisSize.min,
        children: const [
          Text('Currency'),
          TextField(),
          ],
        )
    )
    

    我希望就是这样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-09
      • 2020-12-25
      • 2021-09-01
      • 1970-01-01
      • 2017-09-06
      • 2017-08-10
      • 2021-02-20
      • 1970-01-01
      相关资源
      最近更新 更多