一步一步搭建Flutter開發架子-國際化,路由,本地化,響應式

一天清晨發表於2021-03-01

接上一篇文章,這篇文章主要介紹,路由管理,國際化管理,響應式管理方法,資料持久化管理。還是先看看大神麼們都是怎麼寫的,從中學習一下。看到又一個比較好用的庫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...

  • 網路請求
  • 頁面不同狀態展示封裝

相關文章