ChatGPT解决这个技术问题 Extra ChatGPT

如何将 ListView 添加到 Flutter 中的列?

我正在尝试为我的 Flutter 应用程序构建一个简单的登录页面。我已经成功构建了 TextFields 和登录/登录按钮。我想添加一个水平 ListView。当我运行代码时,我的元素消失了,如果我在没有 ListView 的情况下执行它,它又可以了。我怎样才能正确地做到这一点?

return new MaterialApp(
        home: new Scaffold(
          appBar: new AppBar(
            title: new Text("Login / Signup"),
          ),
          body: new Container(
            child: new Center(
              child: new Column(
              mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  new TextField(
                    decoration: new InputDecoration(
                      hintText: "E M A I L    A D D R E S S"
                    ),
                  ),
                  new Padding(padding: new EdgeInsets.all(15.00)),
                  new TextField(obscureText: true,
                    decoration: new InputDecoration(
                      hintText: "P A S S W O R D"
                    ),
                    ),
                  new Padding(padding: new EdgeInsets.all(15.00)),
                  new TextField(decoration: new InputDecoration(
                    hintText: "U S E R N A M E"
                  ),),
                  new RaisedButton(onPressed: null,
                  child:  new Text("SIGNUP"),),
                  new Padding(padding: new EdgeInsets.all(15.00)),
                  new RaisedButton(onPressed: null,
                  child: new Text("LOGIN"),),
                  new Padding(padding: new EdgeInsets.all(15.00)),
                  new ListView(scrollDirection: Axis.horizontal,
                  children: <Widget>[
                    new RaisedButton(onPressed: null,
                    child: new Text("Facebook"),),
                    new Padding(padding: new EdgeInsets.all(5.00)),
                    new RaisedButton(onPressed: null,
                    child: new Text("Google"),)
                  ],)

                ],
              ),
            ),
            margin: new EdgeInsets.all(15.00),
          ),
        ),
      );

M
MaNDOOoo

我也有这个问题。我的解决方案是使用 Expanded 小部件来扩展剩余空间。

Column(
  children: <Widget>[
    Expanded(
      child: horizontalList,
    )
  ],
);

这是一个很好的解决方案,因为它允许 ListView 的可变大小的高度/宽度,例如当您希望它只占用剩余空间时。当很难知道确切的高度/宽度时,它允许您考虑不同的屏幕尺寸。
这应该是公认的答案。此解决方案允许 ListView 占据屏幕的其余部分,而无需处理媒体查询。
我对 Flutter 太陌生了,不知道为什么会这样,但我很高兴它确实如此。谢谢你。 Flutter 的错误消息对于非专家解释这个问题的根本原因并不是很有帮助。
简单,我在找什么。!不过,性能和渲染会受到影响吗?
有人可以解释导致此问题的原因以及为什么 Expanded 会解决此问题吗?
C
CopsOnRoad

错误原因:

Column 扩展到主轴方向(垂直轴)的最大尺寸,ListView 也是如此。

解决方案:

因此,您需要限制 ListView 的高度。有很多方法,你可以选择最适合你需要的。

如果要允许 ListView 占用 Column 内的所有剩余空间,请使用 Expanded。 Column( children: [ Expanded( // <-- 使用 Expanded child: ListView(...), ) ], )

如果要将 ListView 限制在某个高度,请使用 SizedBox。 Column( children: [ SizedBox( height: 200, // 约束高度。child: ListView(...), ) ], )

如果您的 ListView 很小,您可以尝试对其使用 shrinkWrap 属性。 Column(children: [ ListView(shrinkWrap: true, // 设置这个 ) ], )

如果您想让 ListView 尽可能小,请使用 Flexible 和 ListView.shrinkWrap: Column( children: [ Flexible( // <-- Use Flexible child: ListView(shrinkWrap: true, // 并设置这个 ), ) ], )


你的第三点是我强烈建议所有初学者注意的!
请记住,列表视图也可以随宽度扩展,因此如果您的 SizedBox 不起作用,请包括宽度限制。
G
German Saprykin

您可以检查控制台输出。它打印错误:

在 performResize() 期间抛出了以下断言:水平视口的高度没有限制。视口在横轴上扩展以填充其容器并约束其子级以匹配其在横轴上的范围。在这种情况下,水平视口被赋予了无限量的垂直空间来扩展。

您需要在水平列表中添加高度约束。例如用高度包装在容器中:

Container(
  height: 44.0,
  child: ListView(
    scrollDirection: Axis.horizontal,
    children: <Widget>[
      RaisedButton(
        onPressed: null,
        child: Text("Facebook"),
      ),
      Padding(padding: EdgeInsets.all(5.00)),
      RaisedButton(
        onPressed: null,
        child: Text("Google"),
      )
    ],
  ),
)

接下来的两个答案给出另外两个解决方案并解释发生了什么。
有什么建议使用动态高度而不是固定列表视图的高度吗?
J
Jitesh Mohite

Expanded Widget 会在可用空间的情况下尽可能地增加它的大小 由于 ListView 本质上具有无限的高度,因此会导致错误。

 Column(
  children: <Widget>[
    Flexible(
      child: ListView(...),
    )
  ],
)

在这里我们应该使用 Flexible 小部件,因为即使没有足够的小部件在全屏上呈现,它也只会占用展开后全屏所需的空间。


这是正确的解决方案!多谢兄弟
D
Developine

我有 SingleChildScrollView 作为父级,一个 Column 小部件,然后是列表视图小部件作为最后一个子级。

在列表视图中添加这些属性对我有用。

  physics: NeverScrollableScrollPhysics(),
  shrinkWrap: true,
  scrollDirection: Axis.vertical,

scrollDirection: Axis.vertical 是默认值,因此这不是解决方案的一部分。此外,这会禁用列表上的滚动。
这必须是一个公认的答案!扩展和灵活的问题是 flex,它占用了您为不同的灵活小部件计划的所有空间。 shrinkWrap 解决了这个问题,而 physics 禁用了溢出滚动效果。
U
UN..D

正如上面其他人所提到的,使用 Expanded 包装列表视图是解决方案。

但是当您处理嵌套列时,您还需要将 ListView 限制在一定的高度(经常遇到这个问题)。

如果有人有其他解决方案,请在评论中提及或添加答案。

例子

  SingleChildScrollView(
   child: Column(
     children: <Widget>[
       Image(image: ),//<< any widgets added
       SizedBox(),
       Column(
         children: <Widget>[
           Text('header'),  //<< any widgets added
            Expanded(child: 
            ListView.builder(
              //here your code
               scrollDirection: Axis.horizontal,
        itemCount: items.length,
        itemBuilder: (BuildContext context, int index) {
            return Container();
                   } 
         )
        ),
        Divider(),//<< any widgets added
         ],
       ),

     ],
   ), 
  );

在嵌套列中不要使用扩展只使用 shrikWrap:true,物理:listView 中的 NeverScrollPhysics() 属性
用 SingleChildScrollView 小部件包装溢出的 Column 小部件(检查终端中的错误消息,您应该会看到导致错误的文件和行)对我有用。
感谢您的回复,现在您可以使用 @CopsOnRoad aboce 提到的 shrink 、 sizedbx 或 flexiable with fit
R
Richie

实际上,当您阅读文档时,ListView 应该在 Expanded Widget 内,这样它才能工作。

  Widget build(BuildContext context) {
return Scaffold(
    body: Column(
  children: <Widget>[
    Align(
      child: PayableWidget(),
    ),
    Expanded(
      child: _myListView(context),
    )
  ],
));

}


M
Moein Fazeli

您可以使用 FlexFlexible 小部件。例如:

Flex(
direction: Axis.vertical,
children: <Widget>[
    ... other widgets ...
    Flexible(
        flex: 1,
        child: ListView.builder(
        itemCount: ...,
        itemBuilder: (context, index) {
            ...
        },
        ),
    ),
],

);


为什么选择 Flex?你可以解释吗?我认为 OP 正在询问如何专门在 Column 中添加 ListView。
E
Eric Aig
  Column(
    children: <Widget>[
      Text('Leading text widget'),
      ListView(
        shrinkWrap: true,
        physics: NeverScrollableScrollPhysics(),
        children: <Widget>[
          ListTile(
            leading: Icon(Icons.map),
            title: Text('Map'),
          ),
          ListTile(
            leading: Icon(Icons.photo_album),
            title: Text('Album'),
          ),
          ListTile(
            leading: Icon(Icons.phone),
            title: Text('Phone'),
          ),
        ],
      ),
      Text('More widget'),
    ],
  );

只需使用

shrinkWrap: true,

physics: NeverScrollableScrollPhysics(),

列表视图中的属性


介意解释一下你的答案吗?
问题是how to add listview in a column我认为这为我解决了这个问题。想知道为什么这没有被投票。也许我从那里的流行答案中遗漏了一些东西?
我需要将 Column 包装为 SingleChildScrollViewchild
k
krupesh Anadkat

[解决方案预览] - [列表项是可滚动的,但标题是固定的]

https://i.stack.imgur.com/anDyl.png

我有非常小而直接的答案,请参阅将 listview 放在列中将强制列无限扩展,这基本上是一个错误。

现在,如果您像其他人建议的那样将 physics: NeverScrollableScrollPhysics(), 放在 listview 中,那么如果您禁用其中的滚动,那么拥有 listview 的意义何在..

有一个简单的解决方法,坦率地说,我是通过命中和试验来解决这个问题的。让我在代码之后给你一个小解释。

Column(
      children: [
        Text(
          "All Bookings",
          style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600, color: Colors.brown[700]),
        ),
        Expanded(
          child: Container(
            margin: EdgeInsets.only(top: 24),
            child: ListView.builder(
              itemCount: 30,
              itemBuilder: (BuildContext context, int index) => ListTile(
                title: Text("List Item ${index + 1}"),
              ),
            ),
          ),
        ),
      ],
    )

我需要在 Column 中将标题作为第一个元素,然后放置一个 Listview 以便用户可以拥有滚动列表。这是一种通用的要求。你也可以把它放在底部表或模态中。

代码说明:

我将第一个孩子作为列内的标题 ok(我不想滚动,我希望它被修复) 我在列内展开了子项,这就像获取列中的所有“剩余空间”。在里面我保留了容器(只是为了在标题和列表视图之间留一些空间和边距)这是可选的,你可以删除容器,它仍然可以工作。现在 Listview 受到很好的约束,它不会尝试在列中无限拉伸。由于 Expanded 小部件已经对其进行了约束。

如果我在任何地方有错或此代码不起作用,请纠正我(它现在可以正常工作,没有错误:)


F
Farhan Azam

用扩展的小部件包装您的 Listview


您能否详细说明为什么用 Expanded 包装 ListView 可以解决这个问题?
其他几个答案对此进行了更详细的介绍。请在提交新答案之前查看现有答案。如果您发现以前的答案有用,请将它们作为验证其方法的一种方式进行投票。请不要重复答案,除非您要添加更多细节。
m
mahfuz

你需要做两件事:

将列包装在 SingleChildScrollView 中

在 ListView 中添加 shrinkWrap:true 和物理:NeverScrollableScrollPhysics()

为什么有效:

据我了解,NeverScrollableScrollPhysics 禁用 ListView 的滚动。因此,滚动与 SingleChildScrollView 一起使用。如果我错了,请在下面评论。

SingleChildScrollView(
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Text('Filter'),
      ListView.separated(
        shrinkWrap: true,
        physics: NeverScrollableScrollPhysics(),
        itemCount: rides.length,
        itemBuilder: (BuildContext context, int index) {
          # return some widget
        }
      ),


Y
Yash Dhanlobhe

就我而言,我正在使用

单子滚动视图

柱子

容器

FutureBuilder - 列表视图

我想用整个列滚动最后一个滚动视图来添加

physics: NeverScrollableScrollPhysics(),

列表视图中的这一行。


M
Morteza Rastgoo

尝试使用 Slivers:

Container(
    child: CustomScrollView(
      slivers: <Widget>[
        SliverList(
          delegate: SliverChildListDelegate(
            [
              HeaderWidget("Header 1"),
              HeaderWidget("Header 2"),
              HeaderWidget("Header 3"),
              HeaderWidget("Header 4"),
            ],
          ),
        ),
        SliverList(
          delegate: SliverChildListDelegate(
            [
              BodyWidget(Colors.blue),
              BodyWidget(Colors.red),
              BodyWidget(Colors.green),
              BodyWidget(Colors.orange),
              BodyWidget(Colors.blue),
              BodyWidget(Colors.red),
            ],
          ),
        ),
        SliverGrid(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
          delegate: SliverChildListDelegate(
            [
              BodyWidget(Colors.blue),
              BodyWidget(Colors.green),
              BodyWidget(Colors.yellow),
              BodyWidget(Colors.orange),
              BodyWidget(Colors.blue),
              BodyWidget(Colors.red),
            ],
          ),
        ),
      ],
    ),
  ),
)

D
David Buck
return new MaterialApp(
    home: new Scaffold(
      appBar: new AppBar(
        title: new Text("Login / Signup"),
      ),
      body: new Container(
        child: new Center(
          child: ListView(
          //mainAxisAlignment: MainAxisAlignment.center,
          scrollDirection: Axis.vertical,
            children: <Widget>[
              new TextField(
                decoration: new InputDecoration(
                  hintText: "E M A I L    A D D R E S S"
                ),
              ),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new TextField(obscureText: true,
                decoration: new InputDecoration(
                  hintText: "P A S S W O R D"
                ),
                ),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new TextField(decoration: new InputDecoration(
                hintText: "U S E R N A M E"
              ),),
              new RaisedButton(onPressed: null,
              child:  new Text("SIGNUP"),),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new RaisedButton(onPressed: null,
              child: new Text("LOGIN"),),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new ListView(scrollDirection: Axis.horizontal,
              children: <Widget>[
                new RaisedButton(onPressed: null,
                child: new Text("Facebook"),),
                new Padding(padding: new EdgeInsets.all(5.00)),
                new RaisedButton(onPressed: null,
                child: new Text("Google"),)
              ],)

            ],
          ),
        ),
        margin: new EdgeInsets.all(15.00),
      ),
    ),
  );

W
WiRight

此外,您可以尝试使用 CustomScrollView

CustomScrollView(
      controller: _scrollController,
      slivers: <Widget>[
        SliverList(
          delegate: SliverChildBuilderDelegate(
            (BuildContext context, int index) {
              final OrderModel order = _orders[index];

              return Container(
                margin: const EdgeInsets.symmetric(
                  vertical: 8,
                ),
                child: _buildOrderCard(order, size, context),
              );
            },
            childCount: _orders.length,
          ),
        ),
        SliverToBoxAdapter(
          child: _buildPreloader(context),
        ),
      ],
    );

提示:_buildPreloader 返回 CircularProgressIndicatorText

就我而言,我想在 ListView 下显示一些小部件。使用 Column 对我不起作用,因为 Column 内 ListView 周围的小部件始终在屏幕上显示“向上”,例如“绝对位置”

对不起,我的英语不好