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

Cha*_* Jr 60 dart flutter

我正在尝试为我的Flutter应用程序构建一个简单的登录页面.我已经成功构建了TextFields和Login/Signin按钮.我想添加一个水平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),
          ),
        ),
      );
Run Code Online (Sandbox Code Playgroud)

小智 191

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

new Column(
  children: <Widget>[
    new Expanded(
      child: horizontalList,
    )
  ],
);
Run Code Online (Sandbox Code Playgroud)

  • 花了几个小时后,这个解决方案为我工作了!谢谢 (7认同)
  • 这是一个很好的解决方案,因为它允许 ListView 的高度/宽度可变,就像您希望它只占用剩余空间时一样。当您很难知道确切的高度/宽度时,它可以让您考虑不同的屏幕尺寸。 (5认同)
  • 这应该是公认的答案。该解决方案允许 ListView 占据屏幕的其余部分,而无需处理媒体查询。 (3认同)

Ger*_*kin 37

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

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

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

new Container(
  height: 44.0,
  child: 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"),
      )
    ],
  ),
)
Run Code Online (Sandbox Code Playgroud)

  • 接下来的两个答案给出了另外两个解决方案并解释了发生的情况。 (11认同)
  • 有什么建议使用动态高度而不是固定列表视图的高度吗? (2认同)

Cop*_*oad 37

错误原因:

Column会在主轴方向(垂直轴)上扩展到最大尺寸,因此也会扩展ListView

解决方案

因此,您需要限制的高度ListView。这样做的方法很多,您可以选择最适合自己的需求。


  1. 如果要允许ListView占用内部Column使用的所有剩余空间Expanded

    Column(
      children: <Widget>[
        Expanded(
          child: ListView(...),
        )
      ],
    )
    
    Run Code Online (Sandbox Code Playgroud)

  1. 如果您想将限制ListView某些height,您可以使用SizedBox

    Column(
      children: <Widget>[
        SizedBox(
          height: 200, // constrain height
          child: ListView(),
        )
      ],
    )
    
    Run Code Online (Sandbox Code Playgroud)

  1. 如果您ListView很小,则可以shrinkWrap在其上尝试使用物业。

    Column(
      children: <Widget>[
        ListView(
          shrinkWrap: true, // use it
        )
      ],
    )
    
    Run Code Online (Sandbox Code Playgroud)

  • 我强烈建议所有初学者注意你的第三点! (4认同)
  • @DanielVilela 选项 1 应该适合你。如果没有,请将其作为问题发布,如果我有空,我可以回答。 (2认同)

jit*_*555 34

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

 Column(
  children: <Widget>[
    Flexible(
      child: ListView(...),
    )
  ],
)
Run Code Online (Sandbox Code Playgroud)

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


Dev*_*ine 33

我有SingleChildScrollView一个父级,一个ColumnWidget,然后 List View Widget 作为最后一个孩子。

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

  physics: NeverScrollableScrollPhysics(),
  shrinkWrap: true,
  scrollDirection: Axis.vertical,
Run Code Online (Sandbox Code Playgroud)


UN.*_*..D 12

正如上面其他人提到的,用 Expanded 包裹 listview 是解决方案。

但是当您处理嵌套列时,您还需要将 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
         ],
       ),

     ],
   ), 
  );
Run Code Online (Sandbox Code Playgroud)

  • 在嵌套列中不要使用扩展,只需在 listView 中使用 shrikWrap: true,Physics: NeverScolPhysics() 属性 (2认同)

小智 10

实际上,当您阅读文档时,ListView 应该位于 Expanded Widget 内,以便它可以工作。

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

}


Par*_*iya 9

这里有一个非常简单的方法。有不同的方法可以做到这一点,例如您可以通过 获得它ExpandedSizedbox或者Container应该根据需要使用它。

  1. 用途Expanded:一个小部件,扩展的一个孩子RowColumnFlex让孩子充满可用空间。

    Expanded(
        child: ListView(scrollDirection: Axis.horizontal,
            children: <Widget>[
              OutlineButton(onPressed: null,
                  child: Text("Facebook")),
              Padding(padding: EdgeInsets.all(5.00)),
              OutlineButton(onPressed: null,
                  child: Text("Google")),
              Padding(padding: EdgeInsets.all(5.00)),
              OutlineButton(onPressed: null,
                  child: Text("Twitter"))
            ]),
      ),
    
    Run Code Online (Sandbox Code Playgroud)

使用Expanded插件使得的孩子RowColumnFlex扩展以填充沿着主轴线的可用空间(例如,水平地为一个行或垂直于一列)。

  1. 用途SizedBox:指定尺寸的盒子。

    SizedBox(
        height: 100,
        child: ListView(scrollDirection: Axis.horizontal,
            children: <Widget>[
              OutlineButton(
                  color: Colors.white,
                  onPressed: null,
                  child: Text("Amazon")
              ),
              Padding(padding: EdgeInsets.all(5.00)),
              OutlineButton(onPressed: null,
                  child: Text("Instagram")),
              Padding(padding: EdgeInsets.all(5.00)),
              OutlineButton(onPressed: null,
                  child: Text("SoundCloud"))
            ]),
     ),
    
    Run Code Online (Sandbox Code Playgroud)

如果给定一个孩子,这个小部件会强制它的孩子有一个特定的宽度和/或高度(假设这个小部件的父级允许值)。

  1. 用途Container:一个方便的小部件,它结合了常见的绘画定位大小调整小部件。

     Container(
        height: 80.0,
        child: ListView(scrollDirection: Axis.horizontal,
            children: <Widget>[
              OutlineButton(onPressed: null,
                  child: Text("Shopify")),
              Padding(padding: EdgeInsets.all(5.00)),
              OutlineButton(onPressed: null,
                  child: Text("Yahoo")),
              Padding(padding: EdgeInsets.all(5.00)),
              OutlineButton(onPressed: null,
                  child: Text("LinkedIn"))
            ]),
      ),
    
    Run Code Online (Sandbox Code Playgroud)

所有三个的输出将是这样的

在此处输入图片说明


小智 8

用扩展的小部件包裹您的列表视图


mah*_*fuz 7

你需要做两件事:

  • 包裹Column在里面SingleChildScrollView
  • 添加shrinkWrap: truephysics: NeverScrollableScrollPhysics()ListView

为什么它有效:

据我了解,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
        }
      ),

Run Code Online (Sandbox Code Playgroud)


kru*_*kat 7

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

在此输入图像描述

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

现在,如果你physics: NeverScrollableScrollPhysics(),像其他人建议的那样,在列表视图中,那么如果你禁用列表视图中的滚动,那么拥有列表视图有什么意义。

有一个简单的解决办法,坦率地说,我通过点击和尝试找到了这个问题。让我在代码之后给你一些小小的解释。

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}"),
              ),
            ),
          ),
        ),
      ],
    )
Run Code Online (Sandbox Code Playgroud)

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

代码说明:

  1. 我将第一个孩子保留为“列”内的标题(我不想滚动,我希望它被修复)
  2. 我在列内扩展了子项,这就像获取列中的所有“剩余空间”。
  3. 在里面,我保留了容器(只是为了在标题和列表视图之间放置一些空格,并带有边距),这是可选的,您可以删除容器,它仍然可以工作。
  4. 现在列表视图受到了很好的约束,它不会尝试在列中无限拉伸。因为扩展小部件已经限制了它。

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


小智 6

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

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

);


Eri*_*Aig 6

  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'),
    ],
  );
Run Code Online (Sandbox Code Playgroud)

只需使用

shrinkWrap: true,

physics: NeverScrollableScrollPhysics(),
Run Code Online (Sandbox Code Playgroud)

列表视图中的属性