Flutter Getx

1,206 阅读4分钟

Flutter Getx Doc

Flutter状态管理终极方案GetX

GetX 是 Flutter 上的一个轻量且强大的解决方案:高性能的状态管理、智能的依赖注入和便捷的路由管理。 初学觉得功能强大且完善,这里根据参考资料和文档,对它的功能进行简单记录。

1. 路由管理

普通管理

导航到新的页面

Get.to(NextScreen());

原生

Navigator.push(context, MaterialPageRoute<void>(
  builder: (BuildContext context) {
    return NextScreen();
  },
));

关闭SnackBars、Dialogs、BottomSheets或返回。

Get.back();

原生

Navigator.pop(context);

打开新页面,并且用新页面替换旧页面(删除旧页面,如闪屏广告,登录等)

Get.off(NextScreen());

原生

 Navigator.pushReplacement(context, MaterialPageRoute<void>(
      builder: (BuildContext context) {
        return NextScreen();
      },
    ));

打开新页面并删除之前的所有路由

Get.offAll(NextScreen());

原生

Navigator.pushAndRemoveUntil(
  context,
  MaterialPageRoute<void>(
    builder: (BuildContext context) {
      return NextScreen();
    },
  ),
  (Route<dynamic> route) => false,
);

导航到新页面,在返回时接收返回数据:

var data = await Get.to(Payment());

原生

var data = await  Navigator.push(context, MaterialPageRoute<void>(
  builder: (BuildContext context) {
    return NextScreen();
  },
));

带返回值返回前一个路由,配合上面使用

Get.back(reslut:'success');

原生

Navigator.pop(context, 'success');

别名导航

  1. 声明别名
abstract class Routes {
    static const Initial = '/'; 
    static const NextScreen = '/NextScreen'; 
}
  1. 注册路由
abstract class AppPages {
  static final pages = [
    GetPage(
      name: Routes.Initial,
      page: () => HomePage(),
    ),
    GetPage(
      name: Routes.NextScreen,
      page: () => NextScreen(),
    ),
  ];
}

  1. 替换MaterialApp为GetMaterialApp:
void main() {
  runApp(GetMaterialApp(
    debugShowCheckedModeBanner: false,
    initialRoute: '/',
    theme: appThemeData,
    defaultTransition: Transition.fade,
    getPages: AppPages.pages,
    home: HomePage(),
  ));
}

使用

导航到下一个页面

Get.toNamed(Routes.NextScreen);

导航到下一个页面并删除前一个页面

Get.offNamed(Routes.NextScreen);

导航到下一个页面并删除以前所有的页面

Get.offAllNamed(Routes.NextScreen);

发送参数

Get.toNamed(Routes.NextScreen, arguments: '新衣');

获取参数

String name=Get.arguments;

注册路由时也可以标明参数


GetPage(
    name: '/profile/:user',
    page: () => UserProfile(),
),

传参
Get.toNamed("/profile/34954");

接参
print(Get.parameters['user']);

路由监听

GetMaterialApp(
  routingCallback: (routing) {
    if(routing.current == '/second'){
      openAds();
    }
  }
)

免context导航

snackbar

Get.snackbar('Hi',    // title
    'i am a modern snackbar',);  // message


Get.snackbar(
  "Hey i'm a Get SnackBar!",              // title
  "It's unbelievable! I'm using SnackBar without context, without boilerplate, without Scaffold, it is something truly amazing!", // message
  icon: Icon(Icons.alarm),
  shouldIconPulse: true,
  onTap:(){},
  barBlur: 20,
  isDismissible: true,
  duration: Duration(seconds: 3),
);


原生
final snackBar = SnackBar(
  content: Text('Hi!'),
  action: SnackBarAction(
    label: 'I am a old and ugly snackbar :(',
    onPressed: (){}
  ),
);

// 在小组件树中找到脚手架并使用它显示一个SnackBars。
Scaffold.of(context).showSnackBar(snackBar);

Dialogs

image.png

Get.dialog(YourDialogWidget());

Get.defaultDialog(

    onConfirm: () => print("Ok"),

    onCancel: () => print("object"),

    middleText: "Dialog made in 3 lines of code",

);

BottomSheets

Get.bottomSheet(
  Container(
    child: Wrap(
      children: <Widget>[
        ListTile(
          leading: Icon(Icons.music_note),
          title: Text('Music'),
          onTap: () {}
        ),
        ListTile(
          leading: Icon(Icons.videocam),
          title: Text('Video'),
          onTap: () {},
        ),
      ],
    ),
  )
);

2. 国际化

翻译

创建一个类并扩展翻译。

import 'package:get/get.dart';

class Messages extends Translations {
  @override
  Map<String, Map<String, String>> get keys => {
        'zh_CN': {
          'hello': '你好 世界',
        },
        'de_DE': {
          'hello': 'Hallo Welt',
        }
      };
}
使用

只要将.tr追加到指定的键上,就会使用Get.locale和Get.fallbackLocale的当前值进行翻译。

Text('title'.tr);
语言

传递参数给GetMaterialApp来定义语言和翻译

return GetMaterialApp(

    // 你的翻译
    translations: Messages(), 
    
    // 将会按照此处指定的语言翻译
    locale: Locale('zh', 'CN'), 
    
    // 添加一个回调语言选项,以备上面指定的语言翻译不存在
    fallbackLocale: Locale('en', 'US'), 
);
改变语言

Get.updateLocale(locale)来更新语言环境。

var locale = Locale('en', 'US');
Get.updateLocale(locale);

3. 其它

Get 相关
// 检查 snackbar 是否打开
Get.isSnackbarOpen
// 检查 dialog 是否打开
Get.isDialogOpen
// 检查 bottomsheet 是否打开
Get.isBottomSheetOpen


//检查应用程序在哪个平台上运行。
GetPlatform.isAndroid
GetPlatform.isIOS
GetPlatform.isMacOS
GetPlatform.isWindows
GetPlatform.isLinux
GetPlatform.isFuchsia


// 相当于.MediaQuery.of(context).size.height,
Get.height
Get.width
Get.statusBarHeight
Get.bottomBarHeight
Get.size

GetUntil
capitalize(String value) → String?
将字符串中的每个单词大写 Example: your name => Your Name, your name => Your name

capitalizeFirst(String s) → String?
字符串中的第一个字母大写,其他字母小写 Example: your name => Your name

hasCapitalletter(String s) → bool
检查字符串是否至少包含一个大写字母

isAlphabetOnly(String s) → bool
检查字符串是否仅由字母组成。(无空格)

isAPK(String filePath) → bool
检查字符串是否为apk文件

isAudio(String filePath) → bool
检查字符串是否为音频文件

isBlank(dynamic value) → bool?
检查数据是否为null或空(空或仅包含空格

isBool(String value) → bool
检查字符串是否为布尔值。

isCaseInsensitiveContains(String a, String b) → bool
检查a是否包含b(将大写字母和小写字母视为相同)。

isCaseInsensitiveContainsAny(String a, String b) → bool
检查a是否包含b或b是否包含a(将大小写字母视为相同

isDateTime(String s) → bool
检查字符串是否为日期时间(UTC或Iso8601)

isEmail(String s) → bool
检查字符串是否为电子邮件

isEqual(num a, num b) → bool
检查num a是否等于num b

isGreaterThan(num a, num b) → bool
检查num a是否大于num b

isImage(String filePath) → bool
检查字符串是否为图像文件

isMD5(String s) → bool
检查字符串是否为MD5哈希

isNull(dynamic value) → bool
检查数据是否为空。

isNullOrBlank(dynamic value) → bool?
检查数据是否为null或空(空或仅包含空格

isNum(String value) → bool
检查字符串是int还是double

isNumericOnly(String s) → bool
检查字符串是否仅由数字组成

isPhoneNumber(String s) → bool
检查字符串是否为电话号码

removeAllWhitespace(String value) → String
删除字符串中的所有空白 Example: your name => yourname

4. 持久化存储 GetStorage

引入
dependencies:
  get_storage: ^2.0.2
初始化
main() async {
  await GetStorage.init();
  runApp(App());
}
声明
final box = GetStorage();
读取
box.read('quote')
写入
box.write('quote', 'GetX is the best');
删除
box.remove('quote');
监听
box.listen((){
  print('box changed');
});
清除监听
box.removeListen(listen);
监听指定Key
box.listenKey('key', (value){
  print('new key is $value');
});
清除Storage
box.erase();