!android
Provider的核心实际上就是InheritedWidget,它其实是对InheritedWidget的封装,让InheritedWidget在数据管理上可以更加方便的被开发者所使用。编程
InheritedWidget 能实现全局的状态更新,没法解决局部的问题。segmentfault
首先继承 ChangeNotifierapi
class BaseProvide with ChangeNotifier {
CompositeSubscription compositeSubscription = CompositeSubscription();
/// add [StreamSubscription] to [compositeSubscription]
///
/// 在 [dispose]的时候能进行取消
addSubscription(StreamSubscription subscription){
compositeSubscription.add(subscription);
}
@override
void dispose() {
super.dispose();
compositeSubscription.dispose();
}
}
class RegisterPageState extends State<RegisterPage>{
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => RegisterModel(),
child: switchStatusBar2DarkAppbar(
context: context,
title: "provider demo",
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ChildWidgetA(),
SizedBox(height: 24,),
ChildWidgetB()
],
),
)
)
);
}
}
class ChildWidgetA extends StatelessWidget {
@override
Widget build(BuildContext context) {
debugPrint('ChildWidgetA build');
var model = Provider.of<RegisterModel>(context);
return Container(
color: Colors.redAccent,
height: 108,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('ChildA', style: new TextStyle(
color: Colors.black, fontSize: CommounUtil.getSp(15))),
Text('Model data: ${model.valueA}', style: new TextStyle(
color: Colors.black, fontSize: CommounUtil.getSp(15))),
RaisedButton(
onPressed: () => model.addA(),
child: Text('add'),
),
],
),
);
}
}
class ChildWidgetB extends StatelessWidget {
@override
Widget build(BuildContext context) {
debugPrint('ChildWidgetB build');
var model = Provider.of<RegisterModel>(context);
return Container(
color: Colors.blueAccent,
height: 108,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('ChildB', style: new TextStyle(
color: Colors.black, fontSize: CommounUtil.getSp(15))),
Text('Model data: ${model.valueB}', style: new TextStyle(
color: Colors.black, fontSize: CommounUtil.getSp(15))),
RaisedButton(
onPressed: () => model.addB(),
child: Text('add'),
),
],
),
);
}
}
I/flutter (12301): ChildWidgetB build
I/flutter (12301): ChildWidgetA build
I/flutter (12301): ChildWidgetB build
I/flutter (12301): ChildWidgetA build
复制代码
这种方式当viewmodel中有一个属性发生变化时,A和B都会buildmarkdown
单个局部刷新Selector网络
class ChildWidgetC extends StatelessWidget {
@override
Widget build(BuildContext context) {
debugPrint('ChildWidgetC build');
return Selector<RegisterModel, int>(
selector: (context, value) => value.valueA,
builder: (BuildContext context, value, Widget child) {
return Container(
color: Colors.redAccent,
height: 108,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('ChildC',
style: new TextStyle(
color: Colors.black, fontSize: CommounUtil.getSp(15))),
Text('Model data: $value',
style: new TextStyle(
color: Colors.black, fontSize: CommounUtil.getSp(15))),
RaisedButton(
onPressed: () => context.read<RegisterModel>().addA(),
child: Text('add'),
),
],
),
);
});
}
}
class ChildWidgetD extends StatelessWidget {
@override
Widget build(BuildContext context) {
debugPrint('ChildWidgetD build');
return Container(
color: Colors.blueAccent,
height: 108,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('ChildD',
style: new TextStyle(
color: Colors.black, fontSize: CommounUtil.getSp(15))),
Text('Model data: ${context.select((RegisterModel value) => value.valueB)}',
style: new TextStyle(
color: Colors.black, fontSize: CommounUtil.getSp(15))),
RaisedButton(
onPressed: () => context.read<RegisterModel>().addB(),
child: Text('add'),
),
],
),
);
}
}
复制代码
有了Selector以后,就能够在同一个数据模型中,根据条件,筛选出不一样的刷新条件了,这样就能够避免数据模型中的某个属性变换而引发的整个数据模型刷新了。app
详细使用方法参考:pub.flutter-io.cn/packages/pr…框架
apiless
--http_util.dart ------------------dio网络请求初始化封装async
--net_util.dart ------------------get和post请求封装
base
--app_channel.dart ------------------定义不一样的开发环境
--app_config.dart ------------------不一样的开发环境的地址
--base_provider.dart ------------------provider基类
--base_responce.dart ------------------接口返回的数据类型
--base_widge.dart ------------------基本控件封装
--global_provider_manager.dart ------------------全局的model管理
common ------------------ 公共的方法
data ------------------ 接口数据解析
generated------------------国际化代码
http ------------------接口地址
l10n ------------------字符串
--intl_en.arb 英文
--intl_zh.arb 中文
model------------------各个页面请求model
--login_repository.dart
res
--colours.dart------------------颜色的定义
router
--application.dart------------------初始化router
--router_handers.dart------------------定义每一个页面的路由
--routes.dart-----------------配置路由
ui------------------UI页面
utils------------------工具类
viewmodel------------------每一个页面的viewmodel
main_dev.dart,main_test.dart,main_uat.dart,main_online.dart
------------------不一样开发环境的程序入口
class HttpUtil{
static HttpUtil instance;
Dio dio;
BaseOptions options;
static HttpUtil getInstance() {
print('getInstance');
if (instance == null) {
instance = new HttpUtil();
}
return instance;
}
HttpUtil() {
_initDio();
}
_initDio() {
final String token = AppConfig.appTools.getToken();
String baseRequestUrl=Channel.baseURL;
dio = new Dio()
..options = BaseOptions(
baseUrl: baseRequestUrl,
connectTimeout: 20000,
receiveTimeout: 20000)
..interceptors.add(HeaderInterceptor(token))
..interceptors.add(LogInterceptor(responseBody: true, requestBody: true));
}
}
class HeaderInterceptor extends Interceptor {
String token="";
HeaderInterceptor(String token){
this.token=token;
}
@override
onRequest(RequestOptions options) {
if (token != null && token.length > 0) {
options.headers.putIfAbsent('Authorization', () => 'Bearer' + ' ' + token);
}
return super.onRequest(options);
}
}
复制代码
Stream<BaseResponce> get(String url, {Map<String, dynamic> params}) =>
Stream.fromFuture(_get(url, params: params)).asBroadcastStream();
Future<BaseResponce> _get(String url, {Map<String, dynamic> params}) async {
var response = await HttpUtil.getInstance().dio.get(url, queryParameters: params);
var res = BaseResponce.fromJson(response.data);
return res;
}
Stream<BaseResponce> post(String url,{dynamic body}) =>
Stream.fromFuture(_post(url, body)).asBroadcastStream();
Future<BaseResponce> _post(String url, dynamic body) async {
var response;
if(body==null){
response = await HttpUtil.getInstance().dio.post(url);
}else{
response = await HttpUtil.getInstance().dio.post(url, data: body);
}
var res = BaseResponce.fromJson(response.data);
if(res.code!=200){
}
return res;
}
复制代码
详细使用地址:pub.flutter-io.cn/packages/di…
默认会有一个main.dart文件
根据四个环境拷贝该文件并命名为main_dev.dart,main_test.dart,main_uat.dart,main_online.dart
每一个文件初始化不一样的渠道:
1.添加依赖配置
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2 flutter_localizations: #国际化 sdk: flutter 复制代码
2.MaterialApp的localizationsDelegates
MaterialApp(
// theme: ThemeData(
// //项目配置字体,其余主题颜色配置的能够百度
//// fontFamily: Theme.of(context).platform == TargetPlatform.android? (localModel.localeIndex == 1 ? "HanSans":"DIN") : "IOSGILROY",
// ),
debugShowCheckedModeBanner: false,
locale: localModel.locale,
//国际化工厂代理
localizationsDelegates: [
// Intl 插件(须要安装) //S.of(context).title
S.delegate,
RefreshLocalizations.delegate, //下拉刷新
//系统控件 国际化
GlobalCupertinoLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate//文本方向等
],
supportedLocales: S.delegate.supportedLocales,
home: SpalshPage(),
),
复制代码
3.使用本地化的值
安装插件flutterIntl
重启as,菜单栏的Tool下找到Flutter Intl 并选择Initalize for the project
使用Add Locale
生成其余语言的arb文件
使用S.of(context).autoBySystem 能够获取该字符串
1.导入依赖包
dependencies:
flutter:
sdk: flutter
# 路由跳转框架 https://segmentfault.com/a/1190000022349982
fluro: "^1.6.3"
复制代码
2.全局初始化
final router = new Router();///初始化路由
Routes.configureRoutes(router);
Application.router = router;
复制代码
3.定义路由页面
Handler homeHandler= Handler(handlerFunc: (BuildContext context, Map<String, List<String>> parameters){
return homePage();
});
Handler mineHandler= Handler(handlerFunc: (BuildContext context, Map<String, List<String>> parameters){
return minePage();
});
Handler loginHandler= Handler(handlerFunc: (BuildContext context, Map<String, List<String>> parameters){
return LoginPage();
});
Handler xieyiHandler= Handler(handlerFunc: (BuildContext context, Map<String, List<String>> parameters){
String type=parameters['type'].first;
return WebViewPage(type: type,);
});
Handler registerHandler= Handler(handlerFunc: (BuildContext context, Map<String, List<String>> parameters){
return RegisterPage();
});
复制代码
4.配置路径
class Routes{
static String home='/home';
static String mine='/mine';
static String login='/login';
static String xieyi='/xieyi/:type';
static String register='/register';
static void configureRoutes(Router router){
router.define(home, handler: homeHandler);
router.define(mine, handler: mineHandler);
router.define(login, handler: loginHandler);
router.define(xieyi, handler: xieyiHandler);
router.define(register, handler: registerHandler);
}
}
复制代码
详细使用地址:pub.flutter-io.cn/packages/fl…
响应式编程
简单例子:
Rx.timer(1, new Duration(milliseconds: 700)).listen((event) {
requestPerMission(context);
});
复制代码