一步一步搭建Flutter开发架子-国际化,路由,本地化,响应式
接上一篇文章,这篇文章主要介绍,路由管理,国际化管理,响应式管理方法,数据持久化管理。还是先看看大神么们都是怎么写的,从中学习一下。看到又一个比较好用的库getx,方便简介,基本上都包含今天要封装的内容,那就用起来吧。ps:有人可能会有想法说是应该自己写,总用第三方的库,遇到问题不好处理,有点道理,换个想法如果自己没达到那个水平也可以先使用第三方库,好好看看大神的源码,来提升自己。总之所当面看待吧。
引入GetX
在pubspec.yaml文件中加入
dependencies:
get: ^3.24.0
在需要使用的文件中引入
import 'package:get/get.dart'
在main.dart中使用GetMaterialApp替换MaterialApp
return GetMaterialApp(
enableLog: false,
debugShowCheckedModeBanner: false,
defaultTransition: Transition.rightToLeftWithFade,
theme: ThemeData(
primarySwatch: Colors.orange,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: TabBarPage());
路由管理
比较喜欢这个的原因: 不需要获取上下文context直接跳转页面,代码很简洁,并且支持别名路由跳转
效果:
不带参数颇通跳转
Get.to(OtherPage())
带参数跳转
Get.to(OtherPage(id:''))
无返回跳转
比如在登录成功之后的跳转,不能够再返回到登录页面
Get.off(OtherPage(id:''))
跳转到Tabbar页面
比如在商品的详情页面直接跳转到购物车页面,一般购物车页面在Tabbar上。
Get.off(TabbarPage(currentIndex: 1));
别名跳转
这种情况大家可以去看下GetX的文档,这里就不介绍了。因为我不打算在项目里面坐这种跳转。ps:纯个人原因
SnackBars,Dialogs,BottomSheets使用
GetX中,我们也可以不获取上下文context进行跳用SnackBars,Dialogs, BottomSheets使用
SnackBars
效果:
Get.snackbar(
"Hey i'm a Get SnackBar!",
"It's unbelievable! I'm using SnackBar without context, without boilerplate, without Scaffold, it is something truly amazing!",
icon: Icon(Icons.alarm),
shouldIconPulse: true,
barBlur: 20,
isDismissible: true,
duration: Duration(seconds: 3),
backgroundColor: Colors.red);
具体的属性,大家可以点击进去看下源码配置
Dialogs
效果:
Get.defaultDialog(
onConfirm: () => print("Ok"),
buttonColor: Colors.white,
middleText: "Dialog made in 3 lines of code");
也可以弹出自定义的组件
Get.dialog(YourDialogWidget());
BottomSheets
效果:
Get.bottomSheet(Container(
decoration: BoxDecoration(color: Colors.red),
child: Wrap(
children: <Widget>[
ListTile(
leading: Icon(Icons.music_note),
title: Text('Music'),
onTap: () {}),
ListTile(
leading: Icon(Icons.videocam),
title: Text('Video'),
onTap: () {},
),
],
),
));
以上是简单的用法,我们可以新建哥utils文件夹,封装成一个工具类去调用这个方法。
国际化管理
目前涉及到2中模式,
- 根据系统语言设置国际化
- 在应用内设置国际化显示
首先创建一个Languages.dart文件 简单的写了一个hello的中英文含义
import 'package:get/get.dart';
class Languages extends Translations {
@override
Map<String, Map<String, String>> get keys => {
'zh_CN': {
'hello': '你好 世界',
},
'en_US': {
'hello': 'Hallo Welt',
}
};
}
在main.dart中加入代码:
return GetMaterialApp(
translations: Languages(), // 你的翻译
locale: Locale('zh', 'CN'), // 将会按照此处指定的语言翻译
fallbackLocale: Locale('en', 'US'), // 添加一个回调语言选项,以备上面指定的语言翻译不存在
);
显示只需要加入如下就ok。很简单
Text('hello'.tr)
跟随系统语言
ui.window.locale 获取当前系统语言,设置本地语言
GetMaterialApp(
translations: Languages(), // 你的翻译
locale: ui.window.locale, // 将会按照此处指定的语言翻译
fallbackLocale: Locale('en', 'US'), // 添加一个回调语言选项,以备上面指定的语言翻译 不存在
......
)
在应用内设置国际化显示
更新文字显示为中文如下:
var locale = Locale('zh', 'CN');
Get.updateLocale(locale);
多写两句用RadioListTile实现一下效果
RadioListTile(
value: 'chinese',
groupValue: _selected,
title: Text('中文'),
subtitle: Text('中文'),
selected: _selected == 'chinese',
onChanged: (type) {
var locale = Locale('zh', 'CN');
Get.updateLocale(locale);
setState(() {
_selected = type;
});
}),
RadioListTile(
value: 'english',
groupValue: _selected,
title: Text('英文'),
subtitle: Text('英文'),
selected: _selected == 'english',
onChanged: (type) {
var locale = Locale('en', 'US');
Get.updateLocale(locale);
setState(() {
_selected = type;
});
},
),
这是本人测试使用用的代码。看一下效果
响应式管理方法
GetX举例是一个计数器的例子,已经很容易理解了,作用就是不用在引入过多的状态管理的库,比如provide之类的。用法差不多。更简洁。还是记录一下,方便以后查看用
class Controller extends GetxController{
var count = 0.obs;
increment() => count++;
}
lass Home extends StatelessWidget {
@override
Widget build(context) {
// 使用Get.put()实例化你的类,使其对当下的所有子路由可用。
final Controller c = Get.put(Controller());
return Scaffold(
// 使用Obx(()=>每当改变计数时,就更新Text()。
appBar: AppBar(title: Obx(() => Text("Clicks: ${c.count}"))),
// 用一个简单的Get.to()即可代替Navigator.push那8行,无需上下文!
body: Center(child: RaisedButton(
child: Text("Go to Other"), onPressed: () => Get.to(Other()))),
floatingActionButton:
FloatingActionButton(child: Icon(Icons.add), onPressed: c.increment));
}
}
class Other extends StatelessWidget {
// 你可以让Get找到一个正在被其他页面使用的Controller,并将它返回给你。
final Controller c = Get.find();
@override
Widget build(context){
// 访问更新后的计数变量
return Scaffold(body: Center(child: Text("${c.count}")));
}
}
这块还没有在程序中使用,但是状态管理在程序中使用还是很方便的,比如更改用户信息,登录。购物车逻辑中都可以使用
数据持久化管理
这个地方引入了第二个第三方库
flustars: ^0.3.3
# https://github.com/Sky24n/sp_util
# sp_util分拆成单独的库,可以直接引用
sp_util: ^1.0.1
用起来也很方便感觉不错。
为了之后方便使用,现定义一个Global.dart文件,做初始化操作
import 'package:flustars/flustars.dart';
class Global {
static Future initSqutil() async => await SpUtil.getInstance();
}
在main方法中调用:
Global.initSqutil();
接下来进行存储数据以及获取数据的方法,类型包括:字符串,布尔值,对象,数组
举个例子:
存数据
SpUtil.putString( 'login', '登录了',);
取数据
SpUtil.getString('login',defValue: '');
额外提的一点就是存储对象类型数组,分两种形式,getObjList, getObjectList方法
类似泛型的结构, 可以进行转换
List<Map> dataList = SpUtil.getObjList('cityMap', (v) => v);
返回一个Map数组
List<Map> dataList = SpUtil.getObjectList('cityMap');
这个地方可以配合国际化语言切换时使用。比如每次改变语言进行存储。然后每次打开app进行,获取初始化。
one more things...
- 网络请求
- 页面不同状态展示封装
作者:一天清晨
链接:https://juejin.cn/post/6934572753601167374
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。