根据杜文的Flutter实战.将最后一个实例篇转换为项目并运行起来
1.学习连接地址
https://book.flutterchina.club/chapter15/models.html
2.项目地址
https://github.com/FQDEVER/GithubClientDemo.git
3.所有框架
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
json_annotation: ^2.0.0
cached_network_image: ^2.1.0+1
cupertino_icons: ^0.1.3`
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^1.0.0
json_serializable: ^2.0.0
json_model: ^0.0.2
shared_preferences: ^0.5.6
dio: ^3.0.9
provider: ^4.0.5
oktoast: ^2.3.2
flukit: ^1.0.2
4.学习思路
Model类定义
可以使用json_serializable
,josn_model
,json_annotation
使用命令flutter packages pub run json_model
执行获取对应json的dart模型
当然也可以使用一个网站.将json数据copy进去.获取对应的model.地址:https://javiercbk.github.io/json_to_dart/
数据持久化
使用shared_preferences包对需要的信息做持久化处理
全局变量与共享变量
借鉴:应用程序中通常会包含一些贯穿APP生命周期的变量信息,这些信息在APP大多数地方可能都会被用到,比如当前用户信息、Local信息等。在Flutter中我们把需要全局共享的信息分为两类:全局变量和共享状态。全局变量就是单纯指会贯穿整个APP生命周期的变量,用于单纯的保存一些信息,或者封装一些全局工具和方法的对象。而共享状态则是指哪些需要跨组件或跨路由共享的信息,这些信息通常也是全局变量,而共享状态和全局变量的不同在于前者发生改变时需要通知所有使用该状态的组件,而后者不需要。为此,我们将全局变量和共享状态分开单独管理。
全局变量是固定不变的如统一的网络错误提示语等.共享变量是会影响所有相关的Widget.并且随着共享变量而变化.如主题.国际化.字体等
网络接口
现在使用比较的多的还是dio网络库.如果需要做缓存可以研究一下.如果不是很复杂的请求和要求不高.可以简单地了解使用即可
// 登录接口,登录成功后返回用户信息
Future<User> login(String login, String pwd) async {
String basic = 'Basic ' + base64.encode(utf8.encode('$login:$pwd'));
var r = await dio.get(
"/users/$login",
options: _options.merge(headers: {
HttpHeaders.authorizationHeader: basic
}, extra: {
"noCache": true, //本接口禁用缓存
}),
);
//登录成功后更新公共头(authorization),此后的所有请求都会带上用户身份信息
dio.options.headers[HttpHeaders.authorizationHeader] = basic;
//清空所有缓存
Global.netCache.cache.clear();
//更新profile中的token信息
Global.profile.token = basic;
return User.fromJson(r.data);
}
5.主要的逻辑分析:
a.国际化.我使用的是Flutteri18n这个插件.详细使用可参考项目
相关代码:
MaterialApp(
theme: ThemeData(
primarySwatch: themeModel.theme,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
onGenerateTitle: (context){
return S.of(context).app_title;
},
home: HomeRoute(),
locale: localeModel.getLocale(),
supportedLocales: S.delegate.supportedLocales,
localizationsDelegates: const [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
localeListResolutionCallback: (List<Locale> locales,Iterable<Locale> supportedLocales){
if(localeModel.getLocale() != null){
//如果已选定语言,则不跟随系统
return localeModel.getLocale();
} else{
Locale locale;
Locale _locale = locales.first;
if(supportedLocales.contains(_locale)){
locale = _locale;
}else{
locale = Locale("en","US");
}
return locale;
}
},
),
b.用于路由跳转
相关代码:
routes: <String,WidgetBuilder>{
"login": (context) => LoginRoute(),
"themes": (context) => ThemeChangeRoute(),
"language": (context) => LanguageRoute(),
},
使用:
Navigator.of(context).pushNamed("login");
c.登录与数据页面切换逻辑
使用状态管理Provider
.可以使用Consumer指定访问的模型类型.例如: Consumer<UserModel>.
当你在模型中调用 notifyListeners() 时,所有和 Consumer 相关的 builder 方法都会被调用,即可更新更新界面
通过这个状态管理插件.即可实时更新未登录/登录界面.语言环境与主题的切换
最后:该本书细细品读有很多细节值得学习.特别最后的实例项目.有一些架构相关的设计思路
参考:https://book.flutterchina.club/chapter15/models.html