• 0

  • 483

  • 收藏

一步一步搭建Flutter开发架子-国际化,路由,本地化,响应式

perpetual

python交流

1星期前

接上一篇文章,这篇文章主要介绍,路由管理,国际化管理,响应式管理方法,数据持久化管理。还是先看看大神么们都是怎么写的,从中学习一下。看到又一个比较好用的库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...

  • 网络请求
  • 页面不同状态展示封装
免责声明:文章版权归原作者所有,其内容与观点不代表Unitimes立场,亦不构成任何投资意见或建议。

Python

483

相关文章推荐

未登录头像

暂无评论