列表视图构建器内的 Gridview 构建器预加载所有 gridview 项目
Gridview builder inside list view builder preloads all gridview items
我在 ListView 构建器中有一个 GridView 构建器,如下所示(完整的应用程序示例):
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView.builder(
itemCount: 3,
itemBuilder: (BuildContext context, int sectionIndex) {
return GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.only(top: 10),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 111 / 221,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemCount: 50,
itemBuilder: (context, index) {
print("Loading item $sectionIndex $index");
return Text("Item $index");
},
);
},
),
);
}
}
我在日志中得到的是 Loading item $sectionIndex $index
我当前所在部分内的所有索引。
image
但是,如果我单独使用 GridView 而不是 ListView 中的子项,它只会加载大约 10 个项目,当我向下滚动时它会加载更多(这是预期的行为)
你能告诉我在列表视图中使用网格视图我做错了什么吗?
谢谢
试试下面的代码希望对你有帮助。只需在 ListView.builder()
中添加 shrinkWrap
和 physics
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
完整代码:
ListView.builder(
itemCount: 3,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int sectionIndex) {
return GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.only(top: 10),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 111 / 221,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemCount: 50,
itemBuilder: (context, index) {
print("Loading item $sectionIndex $index");
return Text("Item $index");
},
);
},
),
结果屏幕->
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ScrollController _scrollController = ScrollController();
late List<Widget> widgets = [_gridView(), _gridView()];
@override
void initState() {
_scrollController.addListener(() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
setState(() {
setState(() {
widgets.add(_gridView());
});
});
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView.builder(
controller: _scrollController,
shrinkWrap: true,
padding: const EdgeInsets.only(top: 10),
itemCount: widgets.length,
itemBuilder: (context, index) {
if (widgets.length - 1 == index) {
return Center(child: Text("Load more"));
}
return widgets[index];
},
));
}
Widget _gridView() {
return GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.only(top: 10),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 111 / 221,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemCount: 10,
itemBuilder: (context, index) {
return Text("Item $index");
},
);
}
}
这是因为 ListView.builder 的行为,因为 ListView.builder 是 flex widget,可以 expand
它是 scroll direction
中的 length
根据它是 children
并且遵循相同的规则是 GridView.builder。因此,当您在 ListView.builder 中调用 GridView.builder 时,GridView.builder 没有高度限制,因此它会根据可用的 space.
加载所有 child
在调用两个 GridView.builders ListView.builder 后,没有任何滚动就达到了 max length
所以 3rd
GridView.builder 前两个 build
.
不会同时构建
要从 GridView.builder 得到有限的结果,只需 wrap
到 SizedBox
与特定的 height
。
我希望我能够向你解释。
我在 ListView 构建器中有一个 GridView 构建器,如下所示(完整的应用程序示例):
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView.builder(
itemCount: 3,
itemBuilder: (BuildContext context, int sectionIndex) {
return GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.only(top: 10),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 111 / 221,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemCount: 50,
itemBuilder: (context, index) {
print("Loading item $sectionIndex $index");
return Text("Item $index");
},
);
},
),
);
}
}
我在日志中得到的是 Loading item $sectionIndex $index
我当前所在部分内的所有索引。
image
但是,如果我单独使用 GridView 而不是 ListView 中的子项,它只会加载大约 10 个项目,当我向下滚动时它会加载更多(这是预期的行为)
你能告诉我在列表视图中使用网格视图我做错了什么吗?
谢谢
试试下面的代码希望对你有帮助。只需在 ListView.builder()
shrinkWrap
和 physics
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
完整代码:
ListView.builder(
itemCount: 3,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int sectionIndex) {
return GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.only(top: 10),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 111 / 221,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemCount: 50,
itemBuilder: (context, index) {
print("Loading item $sectionIndex $index");
return Text("Item $index");
},
);
},
),
结果屏幕->
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ScrollController _scrollController = ScrollController();
late List<Widget> widgets = [_gridView(), _gridView()];
@override
void initState() {
_scrollController.addListener(() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
setState(() {
setState(() {
widgets.add(_gridView());
});
});
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView.builder(
controller: _scrollController,
shrinkWrap: true,
padding: const EdgeInsets.only(top: 10),
itemCount: widgets.length,
itemBuilder: (context, index) {
if (widgets.length - 1 == index) {
return Center(child: Text("Load more"));
}
return widgets[index];
},
));
}
Widget _gridView() {
return GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.only(top: 10),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 111 / 221,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemCount: 10,
itemBuilder: (context, index) {
return Text("Item $index");
},
);
}
}
这是因为 ListView.builder 的行为,因为 ListView.builder 是 flex widget,可以 expand
它是 scroll direction
中的 length
根据它是 children
并且遵循相同的规则是 GridView.builder。因此,当您在 ListView.builder 中调用 GridView.builder 时,GridView.builder 没有高度限制,因此它会根据可用的 space.
在调用两个 GridView.builders ListView.builder 后,没有任何滚动就达到了 max length
所以 3rd
GridView.builder 前两个 build
.
要从 GridView.builder 得到有限的结果,只需 wrap
到 SizedBox
与特定的 height
。
我希望我能够向你解释。