避免不必要重绘
- 使用
const
和final
- 对于不需要改变的子部件,使用
const
构造函数。这能让Flutter在构建过程中复用相同的实例,减少构建开销。
- 例如,在一个简单的
StatelessWidget
中:
class MyStaticWidget extends StatelessWidget {
const MyStaticWidget({super.key});
@override
Widget build(BuildContext context) {
return const Text('This is a static text');
}
}
shouldRebuild
回调
- 继承
StatefulWidget
时,重写State
类的shouldRebuild
方法。只有当状态变化确实需要重绘时,才返回true
。
- 示例:
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
int counter = 0;
@override
bool shouldRebuild(covariant _MyStatefulWidgetState oldWidget) {
// 这里只在counter变化时才重绘
return oldWidget.counter != counter;
}
@override
Widget build(BuildContext context) {
return Text('Counter: $counter');
}
}
- 局部更新
- 使用
AnimatedBuilder
或ValueListenableBuilder
等,仅对需要更新的部分进行重建。
- 例如,在一个动画场景中:
class AnimatedValueWidget extends StatefulWidget {
const AnimatedValueWidget({super.key});
@override
State<AnimatedValueWidget> createState() => _AnimatedValueWidgetState();
}
class _AnimatedValueWidgetState extends State<AnimatedValueWidget>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
)..repeat(reverse: true);
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform.rotate(
angle: _controller.value * 2 * 3.14159,
child: child,
);
},
child: const Icon(Icons.favorite),
);
}
}
合理组织状态层次结构
- 状态提升
- 将共享状态提升到最近的共同祖先Widget。这样可以避免在多个子部件中重复管理相同状态。
- 例如,有两个子部件
Child1
和Child2
都依赖一个计数器状态:
class ParentWidget extends StatefulWidget {
const ParentWidget({super.key});
@override
State<ParentWidget> createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
int counter = 0;
void incrementCounter() {
setState(() {
counter++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Child1(counter: counter),
Child2(counter: counter, onIncrement: incrementCounter),
],
);
}
}
class Child1 extends StatelessWidget {
final int counter;
const Child1({super.key, required this.counter});
@override
Widget build(BuildContext context) {
return Text('Counter value in Child1: $counter');
}
}
class Child2 extends StatelessWidget {
final int counter;
final VoidCallback onIncrement;
const Child2({super.key, required this.counter, required this.onIncrement});
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onIncrement,
child: Text('Increment in Child2 ($counter)'),
);
}
}
- 使用状态管理库
- 例如使用
provider
库。它提供了一种简单的方式来管理应用状态,并通过ChangeNotifierProvider
等实现状态的共享和响应式更新。
- 首先,定义一个
ChangeNotifier
类来管理状态:
import 'package:flutter/foundation.dart';
class CounterModel extends ChangeNotifier {
int _counter = 0;
int get counter => _counter;
void increment() {
_counter++;
notifyListeners();
}
}
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => CounterModel(),
child: MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Provider Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Consumer<CounterModel>(
builder: (context, model, child) {
return Text('Counter: ${model.counter}');
},
),
ElevatedButton(
onPressed: () {
context.read<CounterModel>().increment();
},
child: const Text('Increment'),
)
],
),
),
),
),
);
}
}