如何在 Flutter 的同一屏幕上沿 ListView 显示小部件?

Posted

技术标签:

【中文标题】如何在 Flutter 的同一屏幕上沿 ListView 显示小部件?【英文标题】:How to show a widget along a ListView on the same screen in Flutter? 【发布时间】:2019-06-01 15:19:35 【问题描述】:

我正在尝试构建一个非常简单的 ToDo 应用程序。它由屏幕顶部的TextFieldButton(一个表单)组成,允许用户将项目添加到位于TextField 下方的ListView

我可以显示TextFieldButton,也可以显示ListView,但是当我尝试同时显示两者时,屏幕是空的。

我错过了什么吗?我尝试将 ListView 显示到 Column 小部件中,但它看起来不起作用。

这是我没有表格的短代码:

import 'package:flutter/material.dart';

void main()
  runApp(MyApp());


class MyApp extends StatelessWidget
  @override
  Widget build(BuildContext context)
    return MaterialApp(
      title: "Mon app",
      home: Scaffold(
        appBar: AppBar(
          title: Text("My app")
        ),
        body: Column(
          children: <Widget>[
            ListView(
          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'),
            ),
          ],
        )
          ])),
      );
  

谢谢!

【问题讨论】:

【参考方案1】:

ListView 的垂直视口被赋予了无限的高度。用Expanded 小部件包裹你的ListView

import 'package:flutter/material.dart';

void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: "Mon app",
      home: Scaffold(
          appBar: AppBar(title: Text("My app")),
          body: Column(children: <Widget>[
            RaisedButton(onPressed: () ),
            Expanded(
              child: ListView(
                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'),
                  ),
                ],
              ),
            )
          ])),
    );
  

【讨论】:

【参考方案2】:

您应该在 ListView 周围使用Expanded 小部件。所做的是扩展其子级(在本例中为 ListView)以适应父级上的最大可用空间,不包括其他小部件占用的空间。

然后,当您想在底部添加输入时,您可以将普通小部件放在Column 内,但在ListView 之外,因此列表将滚动并且 TextField 将始终保持在页面底部。

这是准备好底部输入的代码,但我建议您尝试仔细了解 Columns、Rows 和 Expanded 小部件的情况。

import 'package:flutter/material.dart';

void main()
  runApp(MyApp());


class MyApp extends StatelessWidget
  @override
  Widget build(BuildContext context)
    return MaterialApp(
      title: "Mon app",
      home: Scaffold(
          appBar: AppBar(
              title: Text("My app")
          ),
          body: Column(
            mainAxisSize: MainAxisSize.max,
              children: <Widget>[
                Expanded(
                  child: ListView(
                    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'),
                      ),
                    ],
                  ),
                ),
                Row(
                  children: <Widget>[
                    Expanded(
                      child: TextField(
                        decoration: InputDecoration(
                          hintText: "What to do?"
                        ),
                      ),
                    ),
                    IconButton(
                      icon: Icon(Icons.send),
                      onPressed: ()
                        //do something
                      ,
                    )
                  ],
                )
              ],
          ),
      ),
    );
  

【讨论】:

【参考方案3】:

另一个更好的解决方案是将其变形为灵活:

Flexible:  
  child: 
    Listview.builder 
      // following two lines needed to make it work
      shrinkWrap: true
      physics: ScrollPhysics(),
      // the rest of your code
    

请记住避免边界错误和抖动警告以及正确显示列表所需的两行代码。

【讨论】:

以上是关于如何在 Flutter 的同一屏幕上沿 ListView 显示小部件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 的同一屏幕中管理两个带有数据的 ListView

Flutter ListVİew 总是在向上或向下滚动时重新渲染

Flutter 如何使用 ListView 水平和 GridView 垂直滚动屏幕

Flutter,如何将exist Bloc用于其他屏幕?

Flutter:使用不同的数据和返回按钮刷新同一屏幕

Flutter 导航,重新打开页面而不是再次推送