常用方法和原则
- Widget复用:通过
Key
来标识和复用Widget。例如在列表中,若列表项是固定不变的,可以给列表项的Widget添加Key
,这样Flutter框架在重建时会复用具有相同Key
的Widget,减少新Widget对象的创建。
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return KeyedSubtree(
key: ValueKey(items[index].id),
child: MyListItemWidget(item: items[index]),
);
},
);
- 懒加载:对于一些不立即需要的Widget,使用
FutureBuilder
或StreamBuilder
进行懒加载。比如在一个页面中有一个图片列表,当用户滚动到某个位置时才加载该位置的图片Widget。
FutureBuilder(
future: _fetchImageData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return ImageWidget(data: snapshot.data);
} else {
return CircularProgressIndicator();
}
},
);
- 局部重建:将界面拆分成独立的小Widget,这样当数据变化时,只有相关的小Widget会重建,而不是整个页面的Widget树。例如一个用户信息展示页面,将头像、用户名、用户简介分别封装成不同的Widget,当用户名更新时,只有用户名对应的Widget会重建。
class UserInfoWidget extends StatelessWidget {
final User user;
UserInfoWidget({required this.user});
@override
Widget build(BuildContext context) {
return Column(
children: [
AvatarWidget(user: user),
UsernameWidget(user: user),
BioWidget(user: user),
],
);
}
}
- 避免不必要的Widget创建:在
build
方法中避免创建不必要的临时Widget。例如在build
方法中重复创建一个常量Widget是没有必要的,可以将其定义为类的成员变量。
class MyWidget extends StatelessWidget {
final MyConstantWidget _constantWidget = MyConstantWidget();
@override
Widget build(BuildContext context) {
return Column(
children: [
_constantWidget,
// other widgets
],
);
}
}
- 使用
Offstage
和Visibility
:Offstage
可以将Widget从渲染树中移除但保留其状态,Visibility
可以控制Widget是否可见但仍在渲染树中。当某个Widget在特定条件下不需要渲染时,可使用Offstage
。例如一个高级设置面板,默认不显示,只有用户点击高级设置按钮时才渲染。
Offstage(
offstage:!showAdvancedSettings,
child: AdvancedSettingsWidget(),
)