代码
class Example extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Example"), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // 使用Consumer部件获取UserModel实例并订阅其变化 Consumer<UserModel>( builder: (_, userModel, child) { // 在数据更新时,重新构建子部件,并显示userModel的name属性 return Text(userModel.name, style: const TextStyle( color: Colors.red, fontSize: 30 ) ); }, ), // 使用Consumer部件获取UserModel实例并订阅其变化 Consumer<UserModel>( builder: (_, userModel, child) { // 在数据更新时,重新构建子部件,并显示一个按钮,点击按钮会调用changeName方法改变name的值 return Padding( padding: const EdgeInsets.all(20), child: ElevatedButton( onPressed: (){ userModel.changeName(); }, child: const Text("改变值"), ), ); }, ), ], ), ), ); } }
1、Provider:
通用的提供者,可用于共享任何对象,不仅仅是状态对象。在更新时,提供者会重新构建依赖于该对象的部件。
创建模型
//1 最基本的Provider组件,可以使用它为组件树中的任何位置提供值, //组件但是当该值更改的时候,它并不会更新UI class UserModel extends ChangeNotifier { String name = "jimi"; void changeName(){ name = "hellp"; print(name); } }
应用程序入口设置
class MyApp9 extends StatelessWidget { const MyApp9({super.key}); @override Widget build(BuildContext context) { return Provider<UserModel>( create: (_) =>UserModel(), child: MaterialApp( debugShowCheckedModeBanner: false, home: Example(), ), ); } }
2、* ChangeNotifierProvider:
用于将一个ChangeNotifier对象共享给其子孙节点,并监听状态变化。会监听模型对象的变化,而且当数据改变时,它也会重建Consumer
(消费者)
创建模型
//2.ChangeNotifierProvider 它跟Provider组件不同, //ChangeNotifierProvider会监听模型对象的变化,而且当数据改变时, //它也会重建Consumer(消费者) class UserModel with ChangeNotifier { String name = "Jimi"; void changeName() { name = "hello"; notifyListeners(); } }
应用程序入口设置
class MyApp9 extends StatelessWidget { const MyApp9({super.key}); @override Widget build(BuildContext context) { return ChangeNotifierProvider<UserModel>( create: (_) =>UserModel(), child: MaterialApp( debugShowCheckedModeBanner: false, home: Example(), ), ); } }
3、FutureProvider:
用于共享Future对象,通常在异步操作和数据加载中使用。
FutureProvider
只会重建一次- 默认显示初始值
- 然后显示
Future
值 - 最后不会再次重建
创建模型
class UserModel { UserModel({required this.name}); String name = "Jimi"; Future<void> changeName() async { print(name); await Future.delayed(const Duration(milliseconds: 2000)); //模拟网络请求延迟两秒后改变其值 name = "hello"; print(name); } } class UserFuture { Future<UserModel> asyncGetUserModel2() async { await Future.delayed(const Duration(milliseconds: 6000)); return UserModel(name: "获取新的数据"); } }
应用程序入口设置
class MyApp9 extends StatelessWidget { const MyApp9({super.key}); @override Widget build(BuildContext context) { return FutureProvider<UserModel>( create: (_) =>UserFuture().asyncGetUserModel2(), initialData: UserModel(name: "hello1"), //必传 不传报错 child: MaterialApp( debugShowCheckedModeBanner: false, home: Example(), ), ); } }
4、StreamProvider:
用于共享流(Stream)对象,可以是Dart中的任何流。和FutureProvider
一样,主要的区别在于值会根据多次触发重新构建UI。
创建模型
//4、StreamProvider提供流值,是围绕StreamBuilder,所提供的值会在传入的时候替换掉新值。 //和FutureProvider一样,主要的区别在于值会根据多次触发重新构建UI。 class UserModel { UserModel({required this.name}); String name = "Jimi"; void changeName() { name = "hello"; } } //每隔一秒钟生成一个数字 class UserStream { Stream<UserModel> getStreamUserModel() { return Stream<UserModel>.periodic(const Duration(milliseconds: 1000), (value) => UserModel(name: "$value") ).take(10); } }
应用程序入口设置
class MyApp9 extends StatelessWidget { const MyApp9({super.key}); @override Widget build(BuildContext context) { return StreamProvider<UserModel>( create: (_) => UserStream().getStreamUserModel(), initialData: UserModel(name: "hello1"), //必传 不传报错 child: MaterialApp( debugShowCheckedModeBanner: false, home: Example(), ), ); } }
5、* MultiProvider
在实际开发过程中肯定会有多个提供者,我们虽然可以采用嵌套的方式来解决,但是这样无疑是混乱的,
可读性级差。这个时候强大的MultiProvder
就产生了;用于在应用程序的根部层次上为子树中的多个小部件提供数据共享;
创建模型
class UserModel1 with ChangeNotifier { String name = "Jimi"; void changeName() { name = "hello"; notifyListeners(); } } class UserModel4 with ChangeNotifier { String name = "Jimi"; int age = 18; void changeName() { name = "hello"; age = 20; notifyListeners(); } }
应用程序入口设置
return MultiProvider( providers: [ ChangeNotifierProvider<UserModel1>(create: (_) => UserModel1()), ChangeNotifierProvider<UserModel4>(create: (_) => UserModel4()), /// 添加更多 ], child: MaterialApp( debugShowCheckedModeBanner: false, home: MultiProviderExample(), ), );
使用数据
class MultiProviderExample extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("MultiProviderExample"), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Consumer<UserModel1>( builder: (_, userModel, child) { return Text(userModel.name, style: TextStyle( color: Colors.red, fontSize: 30 ) ); }, ), Consumer<UserModel4>( builder: (_, userModel, child) { return Text(userModel.age.toString(), style: TextStyle( color: Colors.green, fontSize: 30 ) ); }, ), Consumer2<UserModel1, UserModel4>( builder: (_, userModel1, userModel4, child) { return Padding( padding: EdgeInsets.all(20), child: ElevatedButton( onPressed: (){ userModel1.changeName(); userModel4.changeName(); }, child: Text("改变值"), ), ); }, ), ], ), ), ); } }
6、ProxyProvider:
用于根据其他提供者的值计算新值,并将新值共享给下游部件。
当我们有多个模型的时候,会有模型依赖另一个模型的情况,在这种情况下,
我们可以使用ProxyProvider
从另一个提供者获取值,然后将其注入到另一个提供者中。
创建模型
class UserModel5 with ChangeNotifier { String name = "Jimi"; void changeName({required String newName}) { name = newName; notifyListeners(); } } class WalletModel { UserModel5? userModel5; WalletModel({this.userModel5}); void changeName() { userModel5?.changeName(newName: "JIMI"); } }
应用程序入口设置
class MyApp9 extends StatelessWidget { const MyApp9({super.key}); @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider<UserModel5>(create: (_) => UserModel5()), ProxyProvider<UserModel5, WalletModel>( update: (_, userModel5, walletModel) => WalletModel(userModel5: userModel5), ) ], child: MaterialApp( debugShowCheckedModeBanner: false, home: ProxyProviderExample(), ), ); } }
使用数据
class ProxyProviderExample extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("ProxyProviderExample"), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Consumer<UserModel5>( builder: (_, userModel, child) { return Text(userModel.name, style: const TextStyle( color: Colors.red, fontSize: 30 ) ); }, ), Consumer<UserModel5>( builder: (_, userModel, child) { return Padding( padding: EdgeInsets.all(20), child: ElevatedButton( onPressed: (){ userModel.changeName(newName: "hello"); }, child: Text("改变值"), ), ); }, ), Consumer<WalletModel>( builder: (_, walletModel, child) { return Padding( padding: EdgeInsets.all(20), child: ElevatedButton( onPressed: (){ walletModel.changeName(); }, child: Text("通过代理改变值"), ), ); }, ), ], ), ), ); } }
7、* ChangeNotifierProxyProvider
和ProxyProvider
原理一样,唯一的区别在于它构建和同步ChangeNotifier
的ChangeNotifierProvider
,当提供者数据变化时,将会重构UI。
创建模型
1.
class BookModel { static var _books = [ Book(1, "夜的命名数"), Book(2, "大奉打更人"), Book(3, "星门"), Book(4, "大魏读书人"), Book(5, "我师兄实在太稳健了"), Book(6, "深空彼岸"), ]; // 获取书籍长度 int get length => _books.length; // 根据ID获取书籍 Book getById(int id) => _books[id -1]; // 根据索引获取数据 Book getByPosition(int position) => _books[position]; // 更多.... } class Book { final int bookId; final String bookName; Book(this.bookId, this.bookName); }
2.
class BookManagerModel with ChangeNotifier { // 依赖bookModel final BookModel _bookModel; // 获取数据所有的ID List<int>? _bookIds; // 构造函数 BookManagerModel(this._bookModel, {BookManagerModel? bookManagerModel}) : _bookIds = bookManagerModel?._bookIds ?? []; // 获取所有的书 List<Book> get books => _bookIds!.map((id) => _bookModel.getById(id)).toList(); // 根据索引获取数据 Book getByPosition(int position) => books[position]; // 获取书籍的长度 int get length => _bookIds?.length ?? 0; // 添加书籍 void addFaves(Book book) { _bookIds!.add(book.bookId); notifyListeners(); } // 删除书籍 void removeFaves(Book book) { _bookIds!.remove(book.bookId); notifyListeners(); } } 复制代码
应用程序入口设置
return MultiProvider( providers: [ Provider(create: (_) => BookModel()), ChangeNotifierProxyProvider<BookModel, BookManagerModel>( create: (_) => BookManagerModel(BookModel()), update: (_, bookModel, bookManagerModel) => BookManagerModel(bookModel), ) ], child: MaterialApp( debugShowCheckedModeBanner: false, home: ChangeNotifierProxyProviderExample(), ), );
使用数据
1.
class ChangeNotifierProxyProviderExample extends StatefulWidget { @override _ChangeNotifierProxyProviderExampleState createState() => _ChangeNotifierProxyProviderExampleState(); } class _ChangeNotifierProxyProviderExampleState extends State<ChangeNotifierProxyProviderExample> { var _selectedIndex = 0; var _pages = [PageA(), PageB()]; @override Widget build(BuildContext context) { return Scaffold( body: _pages[_selectedIndex], bottomNavigationBar: BottomNavigationBar( currentIndex: _selectedIndex, onTap: (index) { setState(() { _selectedIndex = index; }); }, items: [ BottomNavigationBarItem( icon: Icon(Icons.book), label: "书籍列表" ), BottomNavigationBarItem( icon: Icon(Icons.favorite), label: "收藏" ) ], ), ); } }
2.
class PageA extends StatelessWidget { @override Widget build(BuildContext context) { var bookModel = Provider.of<BookModel>(context); return Scaffold( appBar: AppBar( title: Text("书籍列表"), ), body: ListView.builder( itemCount: bookModel.length, itemBuilder: (_, index) => BookItem(id: index + 1), ), ); } }
3.
class PageB extends StatelessWidget { @override Widget build(BuildContext context) { var bookManagerModel = Provider.of<BookManagerModel>(context); var bookCount = bookManagerModel.length; return Scaffold( appBar: AppBar( title: Text("收藏列表"), ), body: ListView.builder( itemCount: bookCount, itemBuilder: (_, index) => BookItem(id: bookManagerModel.getByPosition(index).bookId), ), ); } }
4.
class BookButton extends StatelessWidget { final Book book; BookButton({ Key? key, required this.book }) : super(key: key); @override Widget build(BuildContext context) { var bookManagerModel = Provider.of<BookManagerModel>(context); return GestureDetector( onTap: bookManagerModel.books.contains(this.book) ? () => bookManagerModel.removeFaves(this.book) : () => bookManagerModel.addFaves(this.book), child: SizedBox( width: 100, height: 60, child: bookManagerModel.books.contains(this.book) ? Icon(Icons.star, color: Colors.red,) : Icon(Icons.star_border), ), ); } }
5.
class BookItem extends StatelessWidget { final int id; BookItem({ Key? key, required this.id }) : super(key: key); @override Widget build(BuildContext context) { var bookModel = Provider.of<BookModel>(context); var book = bookModel.getById(id); return ListTile( leading: CircleAvatar( child: Text("${book.bookId}"), ), title: Text("${book.bookName}", style: TextStyle( color: Colors.black87 ), ), trailing: BookButton(book: book), ); } }
ListenableProxyProvider:
ListenableProxyProvider
是ListenableProvider
的一个变体,但是在使用上和ChangeNotifierProvider
效果惊人的一致
此参考于Flutter Provider状态管理---八种提供者使用分析-腾讯云开发者社区-腾讯云 (tencent.com)
标签:return,name,提供者,Provider,八种,book,context,child,class From: https://www.cnblogs.com/xbinbin/p/17935581.html