面试题答案
一键面试- 使用const构造函数
- 原理:如果一个
StatelessWidget
及其子树在构建后不会发生变化,使用const
构造函数可以让Flutter在编译时识别出该部件不会改变,从而在相同的const
对象之间进行复用,避免不必要的重建。 - 示例:
在使用class MyConstWidget extends StatelessWidget { const MyConstWidget({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const Text('This is a const widget'); } }
MyConstWidget
时:class ParentWidget extends StatelessWidget { const ParentWidget({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const MyConstWidget(); } }
- 原理:如果一个
- 利用
InheritedWidget
- 原理:
InheritedWidget
可以在widget树中共享数据,使依赖该数据的子部件在数据变化时才重建,而不是每次父部件重建时都重建。StatelessWidget
可以依赖InheritedWidget
,只有当InheritedWidget
的数据发生变化时,依赖它的StatelessWidget
才会重建。 - 示例:
首先定义一个
InheritedWidget
:
然后是依赖它的class MyInheritedWidget extends InheritedWidget { final int data; const MyInheritedWidget({required this.data, required Widget child, Key? key}) : super(key: key, child: child); static MyInheritedWidget? of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>(); } @override bool updateShouldNotify(MyInheritedWidget oldWidget) { return data != oldWidget.data; } }
StatelessWidget
:class DependentWidget extends StatelessWidget { const DependentWidget({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final myData = MyInheritedWidget.of(context)?.data; return Text('Data from InheritedWidget: $myData'); } }
- 原理:
- 使用
ValueKey
- 原理:当
StatelessWidget
的父部件重建并生成新的StatelessWidget
实例时,如果StatelessWidget
具有相同的ValueKey
,Flutter会尝试复用该部件,而不是重建它。这适用于StatelessWidget
基于某个特定值(如ID)创建,且该值不变时不需要重建的情况。 - 示例:
在父部件中使用:class MyWidgetWithKey extends StatelessWidget { final int id; const MyWidgetWithKey({required this.id, Key? key}) : super(key: ValueKey(id)); @override Widget build(BuildContext context) { return Text('Widget with id: $id'); } }
这里class ParentWithKeyWidget extends StatefulWidget { const ParentWithKeyWidget({Key? key}) : super(key: key); @override _ParentWithKeyWidgetState createState() => _ParentWithKeyWidgetState(); } class _ParentWithKeyWidgetState extends State<ParentWithKeyWidget> { int myId = 1; @override Widget build(BuildContext context) { return Column( children: [ const MyWidgetWithKey(id: 1), ElevatedButton( onPressed: () { setState(() { myId++; }); }, child: const Text('Increment') ) ] ); } }
MyWidgetWithKey
使用ValueKey(id)
,即使父部件ParentWithKeyWidget
因setState
重建,只要id
不变,MyWidgetWithKey
不会重建。 - 原理:当