无法将ListView设置为LayoutBuilder窗口小部件(Flutter)

时间:2019-06-21 13:40:08

标签: flutter dart

我需要具有这样的结构

enter image description here

我使用LayoutBuilder来获取内容的高度(在 App Bar TabsBottomNavigation之间)。在这里,我构建了Profile Info Container,并希望使用一些List Tiles构建ListView,但是当我尝试在Layout Builder中构建它时,控制台出现错误。

enter image description here

如果我从ListView中创建了LayoutBuilder,那就行了!

请帮助我解决该问题。 我的代码如下:

Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints viewportConstraints) {
        return SingleChildScrollView(
          child: Container(
            child: Column(
              children: <Widget>[
                Container(
                  height: viewportConstraints.maxHeight * .44,
                  color: Theme.of(context).primaryColor,
                  padding: EdgeInsets.only(bottom: 2),
                  child: Align(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        _buildProfileImage(context),
                        SizedBox(height: 17),
                        Text(userName)
                      ],
                    ),
                  ),
                ),
                Expanded(
                  child: ListView(
                    children: <Widget>[
                      ListTile(
                        leading: Icon(Icons.print),
                        title: Text('asdad'),
                      )
                    ],
                  ),
                )
              ],
            ),
          ),
        );
      },
    );
  }

5 个答案:

答案 0 :(得分:1)

在您的情况下,可以使用下面的build方法。 (我已经检查过并且它可以正常工作,所以我希望它也可以在您的情况下工作,并且符合您的要求。)

Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints viewportConstraints) {
        return Container(
          child: Column(
            children: <Widget>[
              Container(
                height: viewportConstraints.maxHeight * .44,
                color: Theme.of(context).primaryColor,
                padding: EdgeInsets.only(bottom: 2),
                child: Align(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      _buildProfileImage(context),
                      SizedBox(height: 17),
                      Text(userName),
                    ],
                  ),
                ),
              ),
              SizedBox(height: 16),
              Flexible(
                child: ListView(
                  children: <Widget>[
                    Card(
                      child: ListTile(
                        leading: Icon(Icons.print),
                        title: Text('asdad'),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        );
      },
    );
  }

我认为SingleChildScrollView在这种情况下是没有用的,因此我将其删除了,但是您可以在填写时使用它。

您仍然需要按照自己的意愿进行UI改进,因为这是您要求的基本结构。

希望这会对您有所帮助。

答案 1 :(得分:0)

Widget build(BuildContext context) {
return Column(
    children:<Widget>[
     Expanded(
      child:LayoutBuilder(
      builder: (BuildContext context, BoxConstraints viewportConstraints) {
        return SingleChildScrollView(
          child: Container(
            child: Column(
              children: <Widget>[
                Container(
                  height: viewportConstraints.maxHeight * .44,
                  color: Theme.of(context).primaryColor,
                  padding: EdgeInsets.only(bottom: 2),
                  child: Align(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        _buildProfileImage(context),
                        SizedBox(height: 17),
                        Text(userName)
                      ],
                    ),
                  ),
                ),
                Expanded(
                  child: ListView(
                    children: <Widget>[
                      ListTile(
                        leading: Icon(Icons.print),
                        title: Text('asdad'),
                      )
                    ],
                  ),
                )
              ],
            ),
          ),
        );
      },
    ),
  ),
 ]
);
}

答案 2 :(得分:0)

 Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints viewportConstraints) {
        return SingleChildScrollView(
          child: ListView(
            shrinkWrap: true,
            children: <Widget>[
             new Container(
                height: MediaQuery.of(context).size.height/3,
                color: Theme.of(context).primaryColor,
                padding: EdgeInsets.only(bottom: 2),
                child: Align(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      _buildProfileImage(context),
                      SizedBox(height: 17),
                      Text(userName)
                    ],
                  ),
                ),
              ),
             new ListView(
                shrinkWrap: true,
                children: <Widget>[
                  ListTile(
                    leading: Icon(Icons.print),
                    title: Text('asdad'),
                  )
                ],
              )
            ],
          ),
        );
      },
    );
  }

答案 3 :(得分:0)

如果您阅读错误日志,则会显示非零的flex传入,但约束不受限制。为了清楚地理解这一点,可以想象Flutter正在尝试绘制一些非有限像素。那是我们的问题。

诸如ListView或SingleChildScrollView之类的小部件是flex小部件,与Column或Row不同,没有限制。

如果您有大小不确定的子项,则必须为ListView定义flex。为此,您既可以为ListView本身也可以为子级使用rinkeWrap或灵活,扩展的小部件。

这是我的解决方案,尽可能简化:

Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints viewportConstraints) {
        return ListView(
          shrinkWrap: true, // That's it
          children: <Widget>[
            Container(
              color: Theme.of(context).primaryColor,
              height: viewportConstraints.maxHeight * .44,
              padding: EdgeInsets.only(bottom: 2),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  _buildProfileImage(context),
                  SizedBox(height: 17),
                  Text(userName)
                ],
              ),
            ),
            ListTile(
              leading: Icon(Icons.print),
              title: Text('asdad'),
            ),
            ListTile(
              leading: Icon(Icons.print),
              title: Text('asdad'),
            ),
            ListTile(
              leading: Icon(Icons.print),
              title: Text('asdad'),
            )
          ],
        );
      },
    );
  }

与此同时,您的孩子过多,无能为力。如果要在“轮廓信息”和“ ListTiles”部分中使用不同的滚动行为,请告诉我,因为我们必须创建另一个ListView来实现。

此外,如果您共享buildProfileImage小部件,我们甚至可以进一步优化代码,因为在这种情况下甚至不需要LayoutBuilder小部件。

答案 4 :(得分:0)

您使用了错误的LayoutBuilder。
应该使用它来更改设备尺寸和/或方向的布局。

您要尝试执行的操作最好通过MediaQuery完成:

MediaQuery.of(context).padding.top //APP bar height
MediaQuery.of(context).padding.bottom //Bottom bar height
MediaQuery.of(context).size.height //Screen height