面试题答案
一键面试1. 使用 StatefulBuilder
在 StatefulWidget
中,如果部分状态更新频繁,可使用 StatefulBuilder
来局部更新状态,避免整个 StatefulWidget
重新构建。例如:
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
int _counter = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('StatefulBuilder Example')),
body: Center(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times: $_counter'),
ElevatedButton(
onPressed: () => setState(() => _counter++),
child: Text('Increment'),
)
],
);
},
),
),
);
}
}
2. 缓存计算结果
对于频繁调用且计算结果不变的函数,缓存其计算结果。可以使用 memoization
技术,例如:
class MyMath {
Map<int, int> _factorialCache = {};
int factorial(int n) {
if (_factorialCache.containsKey(n)) {
return _factorialCache[n]!;
}
if (n == 0 || n == 1) {
return 1;
}
int result = n * factorial(n - 1);
_factorialCache[n] = result;
return result;
}
}
3. 使用 AnimatedBuilder
或 AnimatedWidget
在处理动画等频繁更新场景时,AnimatedBuilder
或 AnimatedWidget
能高效地只更新动画相关部分,而不是整个 StatefulWidget
。例如:
class AnimatedCounter extends StatefulWidget {
@override
_AnimatedCounterState createState() => _AnimatedCounterState();
}
class _AnimatedCounterState extends State<AnimatedCounter>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
);
_animation = Tween<double>(begin: 0, end: 100).animate(_controller);
_controller.repeat(reverse: true);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Center(
child: Text(
_animation.value.toStringAsFixed(0),
style: TextStyle(fontSize: 30),
),
);
},
);
}
}
4. 使用 InheritedWidget
如果需要在多个子组件间共享数据,且数据更新频繁,InheritedWidget
能避免不必要的重新构建。例如:
class MyInheritedWidget extends InheritedWidget {
final int data;
MyInheritedWidget({required Widget child, required this.data})
: super(child: child);
static MyInheritedWidget? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
}
@override
bool updateShouldNotify(MyInheritedWidget oldWidget) {
return data != oldWidget.data;
}
}
class ChildWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final myData = MyInheritedWidget.of(context)?.data;
return Text('Data from InheritedWidget: $myData');
}
}
5. 优化布局
- 避免深层嵌套的布局结构,使用
Flex
布局(如Row
、Column
)替代多层Stack
等复杂嵌套。 - 使用
LayoutBuilder
时,尽量减少其在频繁更新部分的使用,因为它会在布局变化时重新构建。