performance - Flutter ListView in Container Lazy Rendering 和性能
问题描述
我有一长串经常更新的项目。该列表使用包装在容器中的 ListView.builder 呈现以应用边框等。
我的问题是,当 ListView 位于容器中时,所有项目都被渲染,包括屏幕外的元素。由于列表经常重绘,因此严重影响性能。
我创建了两个示例来说明问题。为简单起见,示例是无状态的,在现实生活中,列表是有状态的。
示例 1 - ListView 是根小部件。请注意控制台中仅构建可见卡。 https://dartpad.dev/ac436b786ae48383c107a64bb3db8070
示例 2 - ListView 包装在容器中。请注意,所有卡都已构建。 https://dartpad.dev/109f1f97085c1726c0826f6ea8b731ec
如何制作带有项目列表的可滚动容器,仅呈现可见项目?
示例2的来源在这里:
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SingleChildScrollView(
child: Container(
color: Colors.green,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: 700,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.44),
spreadRadius: 0,
blurRadius: 15,
offset:
Offset(0, 1), // changes position of shadow
),
]),
margin: EdgeInsets.all(24.0),
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: 20,
itemBuilder: (context, index) {
var text = 'Card $index';
print('Building card $text');
return Card(
child: Container(
height: 130,
child: Center(
child: Text(text),
)));
})
]))),
],
))));
}
}
解决方案
您应该为包装在容器中的 listView 设置高度限制。像这样:
class MyApp extends StatelessWidget {
MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SingleChildScrollView(
child: Container(
color: Colors.green,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: 700,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.44),
spreadRadius: 0,
blurRadius: 15,
offset:
Offset(0, 1),
),
]),
margin: EdgeInsets.all(24.0),
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox( // add a SizedBox and set a specific height
height: 1000,
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: 20,
itemBuilder: (context, index) {
var text = 'Card $index';
print('testtest Building card $text');
return Card(
child: Container(
height: 130,
child: Center(
child: Text(text),
)));
}),
)
]))),
],
))));
}
}
推荐阅读
- flutter - Flutter web 接收 POST 参数
- flutter - 颤振中的离线缓存?
- rust - 计算对象 A,然后返回在 Rust 中引用 A 的对象 B
- excel - 如何在Excel中划分日期?
- c - 使用 QEMU 在 LEON3 处理器上运行 .elf 文件
- python - 创建具有字符位置及其相应计数的字典
- android - 用于库模块的 Android CodeCov/Jacoco
- ios - KeyedDecodingContainer 如何实现解码
(_ 类型:T.Type,forKey 键:KeyedDecodingContainer .Key) throws -> T where T: Decodable - excel - 我想根据 excel 中的 2 个给定条件查找多个输出?
- firebase - 如何更改 Cloud Firestore 中的数据库名称