Flutter:ListView 顶部出现意外空白

19

我有以下源代码:

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: CustomScrollView(
      controller: scrollController,
      slivers: <Widget>[
        SliverList(
          delegate: SliverChildBuilderDelegate(
            (context, cardIndex) {
              return Container(
                color: Colors.white,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Text(
                      'Main Course',
                      style: kRestaurantMenuTypeStyle,
                    ),
                    ListView.builder(
                      itemCount: menuCards[cardIndex].menuItems.length,
                      shrinkWrap: true,
                      physics: NeverScrollableScrollPhysics(),
                      scrollDirection: Axis.vertical,
                      itemBuilder: (context, itemIndex) {
                        return RestaurantMenuItem(
                          menuItem: menuCards[cardIndex].menuItems[itemIndex],
                        );
                      },
                    ),
                  ],
                ),
              );
            },
            childCount: menuCards.length,
          ),
        ),
      ],
    ),
  );
}

不幸的是,ListView.builder() 会自动在顶部创建这个额外的空间。如下图所示。即“主菜”和“Pancit Malabon”文本之间的巨大白色空间。

enter image description here

我不明白为什么ListView会这样做。我该如何删除这个空间?

6个回答

46

为了避免listview的这种行为,覆盖padding属性并将其设为[padding]

return ListView.builder(
      padding: EdgeInsets.zero,
      itemCount: data.items.length,
      itemBuilder: (context, index) {}
);

1
请注意,在iOS上存在一个错误,如果您这样做,就无法点击顶部项目。 https://github.com/flutter/flutter/issues/114498 - Oliver Dixon

12
观察您的截图,ListView 滚动到接近屏幕顶部,并且默认情况下,ListView 添加了一些填充以避免遮挡系统 UI。因此,零填充将移除多余的空间。

默认情况下,ListView 会自动填充列表的可滚动边缘,以避免 MediaQuery 填充指示的部分遮挡。要避免这种行为,请使用零填充属性进行覆盖。

来源:ListView

5

我通过如下方式为我的列表视图添加了 padding 以解决这个问题:

ListView.builder(
  padding: EdgeInsets.only(top: 0.0),
  ...
),

我不理解为什么这个解决方案可行。如果有人能解释一下这个 bug,我可以接受他们的回答。


4
您可以使用 MediaQuery.removePadding 将您的列表视图包装起来。
MediaQuery.removePadding(
  context: context,
  removeTop: true,
  child: ListView(...),
)

移除不公开填充属性的部件填充的绝佳解决方案! 我为尝试从Flutter覆盖层中删除CalendarDatePicker添加的意外填充而苦苦挣扎了3个小时,这太棒了! - Neo Liu
现在您可以只设置padding为:EdgeInsets.zero,不需要其他多余的东西了。 - Oliver Dixon
1
这个解决方案完美地运行。 - undefined

0
MediaQuery.removePadding(
              context: context,
              removeTop: true,
              child: Padding(
                padding: EdgeInsets.zero,
                child: ListView.builder(
this will remove any excess padding issue that is hard to solve in the listview.builder

0
是的,这是有意为之的。 如果在ListView之前放置了一个小部件,你应该用一个带有removeTop: true的MediaQuery.removePadding小部件来包裹ListView。
MediaQuery.removePadding(
                context: context,
                removeTop: true,
                child: ListView(...),
)

或者,使用ListView的padding属性,并将其设置为零。

              ListView(
                padding: EdgeInsets.all(0),
),

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接