Listview.builder render all view issue if its child of ScrollView/ Listview/ Listview.builder flutter

huangapple go评论71阅读模式
英文:

Listview.builder render all view issue if its child of ScrollView/ Listview/ Listview.builder flutter

问题

以下是您要求的翻译部分:

As I have a view hierarchy that has a dynamic list widget (using listview.builder arround 100+ view same time), that child of the Listview/ singlechildscrollview.

the issue is when its child of listview/ scroll view at that time Listview.builder render all widget inside it.

I want render only view those displayed as listview.builder behave. (recycle when scroll)

runApp(MyApp( items: List<String>.generate(100, (i) => 'Item $i'), ));

class MyApp extends StatelessWidget {
final List<String> items;
const MyApp({super.key, required this.items});
@Override
Widget build(BuildContext context) {
const title = 'Long List';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: const Text(title),
),
body: ListView(
children: [
Text("Test nexted List rendering"),
ListView.builder(
shrinkWrap: true,
itemCount: items.length,
itemBuilder: (context, index) {
print(index);
return ListTile(
title: Text(items[index]),
);
},
),
],
)),
);
}
}

Listview.builder render all view issue if its child of ScrollView/ Listview/ Listview.builder flutter

Edited

The above example is just a sample, I cant use parent as a Column instead of Listview.
Because My hierarchy is very big. it's a CMS kind of page with around 3-4 parent Listview is there.

Listview &gt; Listview &gt; Listview &gt; Listview.

英文:

As I have a view hierarchy that has a dynamic list widget (using listview.builder arround 100+ view same time), that child of the Listview/ singlechildscrollview.

the issue is when its child of listview/ scroll view at that time Listview.builder render all widget inside it.

I want render only view those displayed as listview.builder behave. (recycle when scroll)

runApp(MyApp(
items: List&lt;String&gt;.generate(100, (i) =&gt; &#39;Item $i&#39;),
));

class MyApp extends StatelessWidget {
final List&lt;String&gt; items;
const MyApp({super.key, required this.items});
@override
Widget build(BuildContext context) {
const title = &#39;Long List&#39;;
return MaterialApp(
  title: title,
  home: Scaffold(
      appBar: AppBar(
        title: const Text(title),
      ),
      body: ListView(
        
        children: [
          Text(&quot;Test nexted List rendering&quot;),
          ListView.builder(
            shrinkWrap: true,
            itemCount: items.length,
            itemBuilder: (context, index) {
              print(index);
              return ListTile(
                title: Text(items[index]),
              );
            },
          ),
        ],
      )),
);
}
}

Listview.builder render all view issue if its child of ScrollView/ Listview/ Listview.builder flutter

Edited

The above example is just a sample, I cant use parent as a Column instead of Listview.
Because My hierarchy is very big. it's a CMS kind of page with around 3-4 parent Listview is there.

Listview &gt; Listview &gt; Listview &gt; Listview.

答案1

得分: 1

shrinkWrap: true 不太好。你可以使用CustomScrollView。

class MyApp extends StatelessWidget {
  final List&lt;String&gt; items;
  const MyApp({super.key, required this.items});
  @override
  Widget build(BuildContext context) {
    const title = 'Long List';
    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: const Text(title),
        ),
        body: CustomScrollView(
          slivers: [
            SliverToBoxAdapter(
              child: Text("Test nexted List rendering"),
            ),
            SliverList(
                delegate: SliverChildBuilderDelegate(childCount: items.length,
                    (context, index) {
              print(index);
              return ListTile(
                title: Text(items[index]),
              );
            }))
          ],
        ),
      ),
    );
  }
}

更多关于 ShrinkWrap vs Slivers | Decoding Flutter 的信息

或者在一般情况下,如果你想让文本始终位于顶部,请使用 body: ColumnExpanded(child: ListView,并删除 shrinkWrap: true

英文:

shrinkWrap: true isnt good. You can use CustomScrolView.

class MyApp extends StatelessWidget {
  final List&lt;String&gt; items;
  const MyApp({super.key, required this.items});
  @override
  Widget build(BuildContext context) {
    const title = &#39;Long List&#39;;
    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: const Text(title),
        ),
        body: CustomScrollView(
          slivers: [
            SliverToBoxAdapter(
              child: Text(&quot;Test nexted List rendering&quot;),
            ),
            SliverList(
                delegate: SliverChildBuilderDelegate(childCount: items.length,
                    (context, index) {
              print(index);
              return ListTile(
                title: Text(items[index]),
              );
            }))
          ],
        ),
      ),
    );
  }
}

More about ShrinkWrap vs Slivers | Decoding Flutter

Or on your general case, if you like to have text always on top, use body:Column and Expnaded(child:ListView by removing shrinkWrap: true.

答案2

得分: 0

阅读链接:https://docs.flutter.dev/cookbook/lists/long-lists

标准的 ListView 构造函数适用于小型列表。要处理包含大量项目的列表,最好使用 ListView.builder 构造函数。

与默认的 ListView 构造函数相比,后者要求立即创建所有项目,而 ListView.builder() 构造函数在滚动到屏幕上时创建项目。

你的 ListView.builder 渲染所有项目是因为父级 ListView 渲染了其中的所有子部件。

解决方法:

ListView 替换为 Column

Column(
 children: [
    Expanded(child: ListView.builder)
  ]
)

预览:即使设置了 shrinkwrap: true,在 ListView.builder 中只渲染了 15 个项目。

Listview.builder render all view issue if its child of ScrollView/ Listview/ Listview.builder flutter

英文:

Read here: https://docs.flutter.dev/cookbook/lists/long-lists

> The standard ListView constructor works well for small lists. To work
> with lists that contain a large number of items, it’s best to use the
> ListView.builder constructor.
>
> In contrast to the default ListView constructor, which requires
> creating all items at once, the ListView.builder() constructor creates
> items as they’re scrolled onto the screen.

Your ListView.builder rendered all items its because the parent ListView is rendered all the children widget inside it.

Workaround:

change the ListView with Column

Column(
 childrem: [
    Expanded(child: ListView.builder)
  ]
)

Preview: only rendered 15 items inside listview builder eventhough its shrinkwrap: true

Listview.builder render all view issue if its child of ScrollView/ Listview/ Listview.builder flutter

答案3

得分: 0

不要使用shrinkWrap = true的ListView。关于此的更多信息请查看这里

替代方案:

使用mainAxisSize: MainAxisSize.min属性的Column,并使用Flexible()让它根据子元素需要扩展,以占用所有可用空间。

Column(
  mainAxisSize: MainAxisSize.min,
  children: [
     items.map((item) => Flexible(child: Text(item))).toList(),
  ],
)
英文:

Don't use ListView with shrinkWrap = true. More about that here.

Alternatives:

Column with property mainAxisSize: MainAxisSize.min and using Flexible() to let it expand as much space that it available to the children.

Column(
  mainAxisSize: MainAxisSize.min,
  children: [
     items.map((item) =&gt; Flexible(child: Text(item))).toList(),
  ],
)

huangapple
  • 本文由 发表于 2023年3月9日 13:24:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75680723.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定