Flutter 中有多种状态管理方案,从简单的 setState 到复杂的第三方库,如 Provider、Riverpod、Bloc 等。下面详细介绍几种常见的状态管理方法,并提供相应的示例代码。
1. setState
setState 是 Flutter 内置的最简单的状态管理方式,适用于管理局部状态。
示例代码:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('setState Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
2. InheritedWidget 和 InheritedModel
InheritedWidget 是 Flutter 提供的一种可以跨组件树传递数据的方式,适用于需要在较大范围内共享状态的数据。
示例代码:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'InheritedWidget Example',
home: CounterProvider(
child: MyHomePage(),
),
);
}
}
class CounterProvider extends InheritedWidget {
final int counter;
final Widget child;
CounterProvider({Key? key, required this.child, this.counter = 0}) : super(key: key, child: child);
static CounterProvider? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<CounterProvider>();
}
@override
bool updateShouldNotify(CounterProvider oldWidget) {
return oldWidget.counter != counter;
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return CounterProvider(
counter: _counter,
child: Scaffold(
appBar: AppBar(
title: Text('InheritedWidget Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Text(
'${CounterProvider.of(context)!.counter}',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
),
);
}
}
3. Provider
Provider 是 Flutter 官方推荐的状态管理包,它是一个封装了 InheritedWidget 的库,更加简洁和强大。
示例代码:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class CounterModel extends ChangeNotifier {
int _counter = 0;
int get counter => _counter;
void increment() {
_counter++;
notifyListeners();
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => CounterModel(),
child: MaterialApp(
title: 'Provider Example',
home: MyHomePage(),
),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counterModel = Provider.of<CounterModel>(context);
return Scaffold(
appBar: AppBar(
title: Text('Provider Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Text(
'${counterModel.counter}',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: counterModel.increment,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
4. Riverpod
Riverpod 是一个更灵活和强大的状态管理库,提供了更好的编译时安全和易用性。
示例代码:
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final counterProvider = StateProvider<int>((ref) {
return 0;
});
void main() => runApp(ProviderScope(child: MyApp()));
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Riverpod Example',
home: MyHomePage(),
);
}
}
class MyHomePage extends ConsumerWidget {
@override
Widget build(BuildContext context, ScopedReader watch) {
final counter = watch(counterProvider).state;
return Scaffold(
appBar: AppBar(
title: Text('Riverpod Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Text(
'$counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read(counterProvider).state++,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
5. Bloc
Bloc 是一种模式,主要用于在 Flutter 应用中实现复杂的业务逻辑,使用了事件驱动和流(Stream)来管理状态。
示例代码:
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
// Event
abstract class CounterEvent {}
class Increment extends CounterEvent {}
// State
class CounterState {
final int counter;
CounterState(this.counter);
}
// Bloc
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterState(0));
@override
Stream<CounterState> mapEventToState(CounterEvent event) async* {
if (event is Increment) {
yield CounterState(state.counter + 1);
}
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Bloc Example',
home: BlocProvider(
create: (context) => CounterBloc(),
child: MyHomePage(),
),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counterBloc = BlocProvider.of<CounterBloc>(context);
return Scaffold(
appBar: AppBar(
title: Text('Bloc Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
return Text(
'${state.counter}',
style: Theme.of(context).textTheme.headline4,
);
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => counterBloc.add(Increment()),
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
这些示例展示了Flutter中各种状态管理方法,从简单到复杂,开发者可以根据具体需求选择合适的方案。