简体   繁体   English

Flutter SingleChildScrollView 内的 ListView.Builder 不可滚动

[英]Flutter ListView.Builder inside SingleChildScrollView not scrollable

I've just began Flutter.我刚开始 Flutter。 I made a HeaderComponent which shows the title "Home" at the top and I used the BubbleBottomNavbar plugin which is displayed at the bottom.我制作了一个 HeaderComponent,它在顶部显示标题“Home”,并使用了底部显示的 BubbleBottomNavbar 插件。 For the moment, I'm using a list of strings as a mock but will later get a lists of news from an API an loop to display as cards.目前,我使用字符串列表作为模拟,但稍后会从 API 中获取新闻列表,并显示为卡片。

I tried to create as many components as I can and wrap them to reuse the same "MainContainer" everywhere.我尝试创建尽可能多的组件并包装它们以在任何地方重用相同的“MainContainer”。 This one will show the HeaderComponent and a list of widgets it will receive in parameters as content.这将显示 HeaderComponent 和它将在参数中作为内容接收的小部件列表。

I want to it to be a scrollable view by default.我希望它默认是一个可滚动的视图。 All its widgets in content are well displayed but I keep seeing the "bottom overflowed..." warning.它在内容中的所有小部件都显示得很好,但我一直看到“底部溢出......”警告。 I tried many components and different way to fix this using Flex component, Expandable, ... but I still can't scroll and keep this warning我尝试了许多组件和不同的方法来使用 Flex 组件、Expandable 来解决这个问题……但我仍然无法滚动并保留这个警告

This is my App Render:这是我的应用程序渲染:

iPhone 应用预览

Here are my build methods:这是我的构建方法:

MainComponent.dart: MainComponent.dart: 主要组件

PostsComponent.dart: PostsComponent.dart: 帖子组件

Thank you for the help you'll provide me感谢您为我提供的帮助

You probably want to have a fixed header and a scrollable list of posts beneath it.你可能想要一个固定的 header和它下面的可滚动的帖子列表 To achieve this, you want to structure the build method of your page like this:为此,您需要像这样构建页面的build方法:

Widget build(BuildContext context){
  return Column(children: <Widget>[
      HeaderComponent(title:"Home", hasBackButton:false),
      ListView.builder(
        ...
      ),
    ],
  )
}

Stacking 2 widgets, that are scrollable on the same axis, into each other, often results in bugs ("unlimited dimension", "overflow", etc.), because there is no clear scroll behaviour for where these 2 components overlap.将可在同一轴上滚动的 2 个小部件相互堆叠通常会导致错误(“无限维度”、“溢出”等),因为对于这两个组件重叠的位置没有明确的滚动行为。

To implement a Sliver behaviour, use, well, Slivers, like SliverList .要实现 Sliver 行为,请使用 Sliver,例如SliverList

May I ask why you have created a custom header and are not using an AppBar ?请问您为什么创建了自定义 header 而没有使用AppBar You can create a custom PreferredSizedWidget that you could pass to your scaffold if you need an excessively customized design (but you can do all elements of your design in the prebuilt AppBar ).如果您需要过度定制的设计(但您可以在预构建的AppBar中完成设计的所有元素),您可以创建一个自定义的PreferredSizedWidget ,您可以将其传递给您的脚手架。

It is recommended in the Flutter documentations for SingleChildScrollView to only use it if necessary, and instead use a ListView instead.SingleChildScrollView的 Flutter 文档中建议仅在必要时使用它,而改为使用 ListView。

When you have a list of children and do not require cross-axis shrink-wrapping behavior, for example a scrolling list that is always the width of the screen, consider ListView, which is vastly more efficient that a SingleChildScrollView containing a ListBody or Column with many children.当您有一个子列表并且不需要跨轴收缩包装行为时,例如始终是屏幕宽度的滚动列表,请考虑 ListView,它比包含 ListBody 或 Column 的 SingleChildScrollView 效率更高很多孩子。

If you made your header an AppBar , you could then use ListView.builder(...) as the body of the scaffold.如果您将 header 设为AppBar ,则可以使用ListView.builder(...)作为脚手架的主体。

But if you are insistent on using SingleChildScrollView for this use case, use a ListBody with your externally built widgets passed in as children.但是,如果您坚持在此用例中使用SingleChildScrollView ,请使用ListBody并将您的外部构建的小部件作为子级传入。 If you want to do in-line generation of the list elements, you can use List.generate to generate the list in-line within ListBody .如果要对列表元素进行内联生成,可以使用List.generateListBody内内联生成列表。

Keep the Column on the outside, with the first child element of the Column your header, then the SingleChildScrollView with ListBody as its child with your list elements as the children.Column保持在外面, Column的第一个子元素是 header,然后是SingleChildScrollViewListBody作为子元素,列表元素作为子元素。

Widget build(BuildContext context) => Column(
 children: <Widget>[
   Header(),
   SingleChildScrollView(
     child: ListBody(
       children: List.generate(...),
     ),
   )
 ],
);

EDIT: Or as the other user recommended, you could nest a ListView within the Column and eliminate the SingleChildScrollView entirely, which is more ideal and much more performant.编辑:或者正如其他用户推荐的那样,您可以在Column中嵌套一个ListView并完全消除SingleChildScrollView ,这更理想且性能更高。

Hye, As I have struggled with finding the answer.惠,因为我一直在努力寻找答案。 But finally I solved it.但最后我解决了。

  1. For those who wants their DataTable to scroll vertical as well as horizontal.对于那些希望他们的 DataTable 垂直和水平滚动的人。
Expanded(
    child: ListView(children: [
      Column(
        children: [
           SingleChildScrollView(
                 scrollDirection: Axis.horizontal,
                 child: DataTable(
                          columns: [
                              DataColumn(label: Text('Storage Location')),
                              DataColumn(label: Text('Piece No ')),
                            ],
                          rows:
                              DataRow(
                                 cells: <DataCell>[
                                            DataCell(Text(element["LGORT"])),
                                            DataCell(Text(element["PCNO"])),
                                                  ],
                                     ),
                               ),
                            ),
                     ],
            ),
       ]),
    )
);

You should make the ListView.builder inside a container, so the builder know where to take its Size(Height,Width from).您应该在容器内创建 ListView.builder,以便构建器知道从哪里获取其 Size(Height,Width)。

Widget build(BuildContext context){
  return Container(
     // You can add its height height here or you can leave it empty
     height : YourHeightValue,
     child: ListView.builder(
       ...
     ),
  )
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM