Flutter 状态管理Provider(一)
2019-08-28 本文已影响0人
emdd2016
Provider是谷歌新推出的一个Flutter状态管理的解决方案。
当然状态管理的解决方案相当的多: Scope, Redux, Stream, Bloc,RxDart 等。
本文通过以下四点来介绍以下Provider的使用,相对于其他的状态管理方案,Provider可以说要简单的多的多。
1. 引用
2. 创建Model
3. 将Model和View建立联系
4. 通过Provider获取到Model,进而进行相关的操作
引用
在 pubspec.yaml 中添加: provider: ^3.1.0 , 版本号换成自己想要的即可。包地址: https://pub.dev/packages/provider#-readme-tab-
创建一个用来管理书籍列表的model,通过接口请求书本列表,然后显示出来
class Book with ChangeNotifier {
List<BookResponseData> _bookList;
List<BookResponseData> get bookList => _bookList;
/// 请求接口获取图书列表
loadBookList() async {
var httpClient = new HttpClient();
var uri = new Uri.https('www.apiopen.top', '/novelApi');
var request = await httpClient.getUrl(uri);
var response = await request.close();
var responseBody = await response.transform(utf8.decoder).join();
// 将获取到的字符串转换成定义好的Book实体类
BookResponseEntity entity =
BookResponseEntity.fromJson(json.decode(responseBody));
_bookList = entity.data;
// 接口返回图书列表后 发送一个通知,通知UI刷新
notifyListeners();
}
@override
void dispose() {
super.dispose();
}
}
通过ChangeNotifierProvider将Model和View建立联系
void main() => runApp(ChangeNotifierProvider<Book>(
builder: (context) => Book(),
child: MainPage(),
));
不通版本的provider,这个参数会有一些不通,使用的时候可以直接点进去看构造方法的参数对应填上即可。
通过Provider获取到Model,进而进行相关的操作
获取的方式是通过: Provider.of <T>(context)
完整可以运行的代码如下(model 的代码在上边有):
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'bean/book_response_entity.dart';
import 'model/book_model.dart';
// 通过 ChangeNotifierProvider 将Book这个model和页面Widget建立联系, 这样在Widget中才可以通过Provider.of(context)来找到。
void main() => runApp(ChangeNotifierProvider<Book>(
builder: (context) => Book(),
child: MainPage(),
));
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "",
home: BookListPage(),
);
}
}
/// 书本列表页面
class BookListPage extends StatefulWidget {
@override
_BookListPageState createState() => _BookListPageState();
}
class _BookListPageState extends State<BookListPage> {
@override
void initState() {
super.initState();
// 由于Provider获取对应的Model需要Context,所以不能直接放到initState 中,在initState中context还没有。
WidgetsBinding.instance.addPostFrameCallback((_) {
// 这个是在页面绘制完成后回调, 那个时候肯定是有context 的
Provider.of<Book>(context).loadBookList();
});
}
@override
Widget build(BuildContext context) {
// 直接通过Provider.of 方法获取到对应的model, 通过model来获取数据或者操作数据。 这里是直接获取到 书本列表
List<BookResponseData> list = Provider.of<Book>(context).bookList;
return Scaffold(
appBar: AppBar(
title: Text("provider demo"),
),
body: Container(
child: ListView(
children: list.map((BookResponseData data) {
// 根据bookList这个数据生成对应的ItemView list .
return Container(
padding: EdgeInsets.all(10.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.lightBlue, width: 1.0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
child: Text(
"${data.bookname}--${data.authorName}",
style: TextStyle(fontWeight: FontWeight.w600),
),
),
Container(
margin: EdgeInsets.only(top: 10.0),
alignment: Alignment.centerLeft,
child: Text(data.bookInfo),
),
],
),
);
}).toList(),
),
),
);
}
}
如此, 简单的Provider的使用就说完了。 相比其他几种状态管理方式真的简单的多。
有任何问题,请留言,大家相互讨论解决。