Flutter中GridView与GridView.builder的核心差异是什么?
GridView与GridView.builder的核心差异解析
为了测试GridView和GridView.builder的懒加载特性,我创建了一个自定义StatelessWidget——AnotherText,它在构建时会打印"build"并显示文本:
class AnotherText extends StatelessWidget { const AnotherText({super.key}); @override Widget build(BuildContext context) { print('build'); return Text('Hello'); } }
随后我分别使用两种构造函数进行测试:
使用GridView.count
GridView.count( crossAxisCount: 2, children: [ AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), AnotherText(), ], ),
使用GridView.builder
GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2), itemBuilder: (context, index) => AnotherText(), itemCount: 100, ),
测试后发现,两者都会在滚动时按需执行子组件的build方法,而非一次性完成所有子组件的构建——也就是说两者都具备懒加载特性。那么它们的核心差异到底是什么?
核心差异
组件实例化时机不同
GridView.count(包括所有直接传入children列表的GridView构造方法):需要提前创建所有子组件的实例并放入children列表。虽然子组件的build方法是懒执行的,但所有子组件的对象实例在GridView初始化时就已经全部创建完毕。比如上面的测试代码里,26个AnotherText对象在GridView初始化时就已经存在,只是它们的build要等到显示时才触发。GridView.builder:不需要提前创建任何子组件实例,它通过itemBuilder回调,在需要显示对应位置的组件时,才会调用回调创建组件实例并执行build方法。比如设置itemCount:100时,初始化阶段不会创建100个AnotherText对象,只有滚动到对应位置时才会触发创建。
内存占用表现不同
- 当子组件数量庞大(比如上千个)时,
GridView.count会因为提前创建所有组件实例,占用更多内存;而GridView.builder只保留当前可见(加上预加载的少量)组件实例,内存占用低得多。
- 当子组件数量庞大(比如上千个)时,
适用场景不同
- 如果子组件数量少、内容固定且明确,使用
GridView.count更简洁直接。 - 如果子组件数量多、内容需要动态生成(比如从数据源获取、按索引配置),必须使用
GridView.builder,既能节省内存,又能避免不必要的实例化操作。
- 如果子组件数量少、内容固定且明确,使用
内容的提问来源于stack exchange,提问作者Yaser Hesham
相关产品推荐
相关产品推荐

