优化策略
- 减少重绘:
- 局部更新:使用
StatefulWidget
管理选中状态,当某个Container
被点击时,只更新该Container
的状态,而不是整个列表。例如,在ListView.builder
中,每个Container
有自己独立的State
对象,这样只有被点击的Container
会重新构建。
- 使用
RepaintBoundary
:将每个Container
包裹在RepaintBoundary
中。这可以限制重绘区域,当Container
状态改变时,只重绘RepaintBoundary
内的部分,而不会影响到整个列表视图。
- 复用Widget:
- ListView.builder:对于大量的
Container
,使用ListView.builder
而不是ListView
。ListView.builder
会按需创建和销毁Widget
,只在需要显示时构建Container
,而不是一次性构建所有的Container
,大大减少内存占用。
- 缓存机制:可以考虑建立一个简单的缓存机制,对于已经构建过的
Container
,如果其状态没有改变,直接复用缓存中的Widget
,避免重复构建。
- 优化装饰绘制:
- 简化装饰:避免使用过于复杂的装饰,如复杂的渐变、多层嵌套的边框等。简单的背景色和边框绘制成本较低。
- 预计算:对于一些固定的装饰属性,如边框宽度、颜色等,可以在初始化时进行预计算,而不是每次构建时计算,减少构建时间。
实现方法
- 使用
StatefulWidget
管理选中状态:
class SelectableContainer extends StatefulWidget {
final int index;
const SelectableContainer({Key? key, required this.index}) : super(key: key);
@override
_SelectableContainerState createState() => _SelectableContainerState();
}
class _SelectableContainerState extends State<SelectableContainer> {
bool isSelected = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
isSelected =!isSelected;
});
},
child: Container(
decoration: BoxDecoration(
color: isSelected? Colors.blue : Colors.white,
border: isSelected
? Border.all(color: Colors.blue, width: 2)
: null,
),
// 其他边距等设置
margin: EdgeInsets.all(10),
child: Text('Container ${widget.index}'),
),
);
}
}
- 在
ListView.builder
中使用:
ListView.builder(
itemCount: largeContainerList.length,
itemBuilder: (context, index) {
return SelectableContainer(index: index);
},
)
- 使用
RepaintBoundary
:
class SelectableContainer extends StatefulWidget {
final int index;
const SelectableContainer({Key? key, required this.index}) : super(key: key);
@override
_SelectableContainerState createState() => _SelectableContainerState();
}
class _SelectableContainerState extends State<SelectableContainer> {
bool isSelected = false;
@override
Widget build(BuildContext context) {
return RepaintBoundary(
child: GestureDetector(
onTap: () {
setState(() {
isSelected =!isSelected;
});
},
child: Container(
decoration: BoxDecoration(
color: isSelected? Colors.blue : Colors.white,
border: isSelected
? Border.all(color: Colors.blue, width: 2)
: null,
),
// 其他边距等设置
margin: EdgeInsets.all(10),
child: Text('Container ${widget.index}'),
),
),
);
}
}