Flutter - 如何让带有孩子的容器占据整个屏幕

Posted

技术标签:

【中文标题】Flutter - 如何让带有孩子的容器占据整个屏幕【英文标题】:Flutter - How to get Container with children to take up entire screen 【发布时间】:2019-07-26 01:38:05 【问题描述】:

根据 Flutter 文档 Containers with no children try to be as big as possible unless the incoming constraints are unbounded, in which case they try to be as small as possible. Containers with children size themselves to their children. 我最接近让它工作的:

return Stack(
  children: <Widget>[
    Container(
      width: MediaQuery.of(context).size.width,
      height: MediaQuery.of(context).size.height,
      //width: Device.screenWidth,
      //height: Device.screenHeight,
      child: Column(
        children: <Widget>[(view[1])],
      ),
    ),
    Container(
      width: MediaQuery.of(context).size.width * .50,
      height: MediaQuery.of(context).size.width * .50,
      child: Column(
        children: <Widget>[(view[0])],
      ),
    ),
  ],
);


I/flutter (12292): The following message was thrown during layout:
I/flutter (12292): A RenderFlex overflowed by 81 pixels on the bottom.
I/flutter (12292): The overflowing RenderFlex has an orientation of Axis.vertical.
I/flutter (12292): The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and
I/flutter (12292): black striped pattern. This is usually caused by the contents being too big for the RenderFlex.

不明白为什么 MediaQuery 或 Device 不能防止溢出?第一个 Container 在 android 手机或平板电脑上总是溢出 81 像素;现在没有要测试的 iPhone 或 iPad。根据我从其他帖子中读到的内容,只需包装在 SingleChildScrollView 中即可更正黄色和黑色溢出,但是当我尝试这样做时,我得到了

child: SingleChildScrollView(
        child: Column(
          children: <Widget>[(view[1])],
        ),
      ),

I/flutter (12292): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (12292): The following assertion was thrown during performLayout():
I/flutter (12292): RenderFlex children have non-zero flex but incoming height constraints are unbounded.
I/flutter (12292): When a column is in a parent that does not provide a finite height constraint, for example if it is
I/flutter (12292): in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
I/flutter (12292): flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
I/flutter (12292): space in the vertical direction.
I/flutter (12292): These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
.
.
.
I/flutter (12292):   crossAxisAlignment: center
I/flutter (12292):   verticalDirection: down
I/flutter (12292): This RenderObject had the following child:
I/flutter (12292):   RenderAndroidView#e356e NEEDS-LAYOUT NEEDS-PAINT

根据我看到的错误,对 Expanded、ClipRect 和其他小部件进行了其他几次尝试,但在根本没有图像的情况下只会让情况变得更糟。我是否遗漏了一些简单的东西,或者我应该尝试以另一种方式解决这个问题?

编辑:根据 Amsakanna,最新尝试低于但仍溢出 81 像素以在第一个代码块中产生相同的错误消息。

return Stack(
  children: <Widget>[
    SingleChildScrollView(
      child: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        child: Column(
          children: <Widget>[view[1])],
        ),
      ),
    ),

I/flutter ( 1144): The following message was thrown during layout:
I/flutter ( 1144): A RenderFlex overflowed by 81 pixels on the bottom.
I/flutter ( 1144): The overflowing RenderFlex has an orientation of Axis.vertical.
I/flutter ( 1144): The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and
I/flutter ( 1144): black striped pattern. This is usually caused by the contents being too big for the RenderFlex.

尝试在 SingleChildScrollView 中使用 IntrinsicHeight,如在 Expanding content to fit the viewport 部分中找到的 here,但它也溢出(81 像素)并显示类似的错误消息。

【问题讨论】:

你想达到什么目的?也许给一些细节。因为一个简单的Stack 和一个Container 作为一个孩子应该使用全屏,如果你把两个Container 作为一个Stack 孩子要注意只有第二个是可见的,毕竟它是一个堆栈,所以它在第一个之上。 (view[0]) 和 (view[1]) 里面是什么?他们可能是问题的根源。 @MiguelRuivo 我将 2 个摄像机视图堆叠在一起。类似于 Android 中的 FrameLayout。目前两者都是可见的,只是第一个反复溢出 @Willy view[0] 和 view[1] 都是相机。根据 MediaQuery.... * 0.50,第二个容器的大小正确,但第一个容器不断溢出。如果它们是问题的根源,我似乎对这两种观点都有疑问...... 在第二个容器中,您设置高度 = 设备宽度。这是故意的还是错字? 【参考方案1】:

您将其包装在 SingleChildScrollView 中是正确的。

第二个错误发生在当你有一个像'Expanded'这样的弹性小部件被放置在一个列中时。如果您没有在第一个 Column 中放置任何展开的小部件,则可能是相机小部件在这样做。

尝试通过将相机小部件包装在 Container 或 SizedBox 中来为其指定一个确定的尺寸

【讨论】:

感谢您发现上面的错字,它应该是 height = ...size.height。是的,视图已扩展为想要填充所有可用空间... 在这种情况下,您应该使用设备宽度和高度的容器将列包装在 SingleChildScrollView 中。【参考方案2】:

SizedBox.expand 为我做了。这是一个显示图像的示例,使图像高度与父级匹配,并且容器在未使用的空间中绘制黑色背景:

  SizedBox.expand(
    child: Container(
      color: Colors.black,
      child: Image (
        fit: BoxFit.fitHeight,
        image: AssetImage('assets/myimage.png'),
      ),
    ),
  );

【讨论】:

【参考方案3】:

它对我有用..

return Scaffold(
              appBar: AppBar(
                title: Text("chatEasy"),
                backgroundColor: Color.fromRGBO(102, 108, 218, 1),
              ),
              body: Container(
                child: Column(
                  children: <Widget>[
                    Expanded(
                      child: Container(
                        child: Image(
                          image: AssetImage("images/baseScreen.png"),
                          fit: BoxFit.fitHeight,
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            );
          
        

【讨论】:

【参考方案4】:

我的方法...

return Scaffold(
      appBar: AppBar(
        title: Text('Title'),
      ),
      body: Container(
        color: Colors.indigo[200],
        alignment: Alignment.center,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Container(
              child: Image.file(_image),
            ),
          ],
        ),
      ),
    );

【讨论】:

请添加更多细节来解释您的解决方案。 @Nakx 检查文档中的“alignment”:“如果非空,容器将扩展以填充其父级并根据给定值将其子级定位在自身内。”指定对齐基本上会使容器扩展以填充父级。【参考方案5】:

使用 SingleChildScrollView() 包装容器,并使用 MediaQuery 为容器指定高度和宽度。我可以使用这种方式实现结果。这样,屏幕就不会溢出任何像素。

return Scaffold(
  body: SingleChildScrollView(
    child: Container(
      height: MediaQuery.of(context).size.height,
      width: MediaQuery.of(context).size.width,
      child: , //child 
    ),
  ),
);

【讨论】:

【参考方案6】:

如果您想让容器的高度与其子容器的高度相同,您可以使用这种方法。

     Card(
           
            child: Flexible(
              child: Container(
                
                child: Column(
                  children: [
                    Container(
                      height: 30,
                      width: double.infinity,
                      color: Theme.of(context).primaryColor,
                        child: Align(
                              alignment: Alignment.centerLeft,
                              child: Container(
                                  margin: EdgeInsets.only(left: 5),
                                  child: Text('Presupuesto Por Profesional',style: 
                  TextStyle(color: Colors.white, fontSize: 16,fontWeight: 
                FontWeight.bold)),
                              )
                        )
                ),
                    ProfessionalTableView(reportData.presupuestos)
                  ],
                ),
              ),
            )
          ),

我的ProfessionalTableView 是一个数据表,它的长度取决于我传递给它的列表的大小。所以卡片的大小也取决于我在列表中的项目。我用Flexible 包裹父级Container 并且它可以工作。

【讨论】:

【参考方案7】:

SizedBox.expand 包裹Container 并在SizedBox 中添加颜色。

【讨论】:

以上是关于Flutter - 如何让带有孩子的容器占据整个屏幕的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Flutter 应用在​​ android 导航栏后面绘制并使导航栏完全透明?

如何安排弹性项目以占据容器的整个宽度?

Flutter - 当兄弟姐妹灵活时,扩展不会占用所有可用空间

如何让“Pointermove”委托在父母/孩子的Safari iOS中工作?

按钮在颤动中占据整个屏幕

Flutter TextButton 占据整个宽度