玩Android Flutter版本,通过项目了解Flutter项目快速搭建开发

继上个月的纯血鸿蒙版的玩Android,这次继续Flutter版本的玩Android实战。整体完成度80%,可自行编译打包使用。不得不说,flutter的生态发展还是挺好的,各种三方开源库、plugin比较完整。这对于项目快速迭代开发还是挺友好的~(该文章同步发布到稀土掘金)

仓库地址

wan_android_flutter

项目介绍

项目common模块封装了常用以下的功能,可用于其他项目的快速迭代开发

  1. 支持浅色/深色模式(跟随系统)
  2. 支持语言切换(跟随系统)
  3. 资源文件管理
  4. 支持toast、支持全局loading
  5. 支持页面导航路由
  6. 通用的appbar
  7. 支持沉浸式状态
  8. ...

相关技术

一、iFlutter插件使用

通过AndroidStudio安装iFlutter plugin,可以加速flutter开发。项目中主要用于:

  • 资源文件管理:避免在代码中硬编码图片名字
  1. 在assets目录存放资源

  2. 通过jFlutter生成AssetsRes文件(iflutter可以设置自动监听文件变化)

  1. 使用

    复制代码
     Image.asset(
       AssetsRes.HEART,
       width: 25,
       height: 25,
     )
  • json转dart:网络请求时特别好用,接口返回数据直接生成相应model
  1. 通过iFlutter生成dart
  1. 输入json,并填写生成dart文件名
二、get_cli

get_cli | Dart package:通过get_cli管理文本

  1. assets/locales下维护各种语言的文本
  1. 通过命令行生成相应的语言文件:locales.g.dart

    get generate locales assets/locales

  2. 代码中使用

    /// 代码使用:通过LocaleKeys.about.tr方式使用
    Text(
    LocaleKeys.about.tr,
    style: colorData.textBlack.s18.regular,
    )

三、getx

get | Flutter package:更便捷的状态管理与路由管理

  1. 状态管理

flutter的组件少不了状态管理,目前开源的方案比较多,这里采用getx

复制代码
/// 需要变更的数据使用obs定义,需要跟随数据变化的widget使用Obx进行包裹即可
class Home extends StatelessWidget {
  var count = 0.obs;
  @override
  Widget build(context) => Scaffold(
      appBar: AppBar(title: Text("counter")),
      body: Center(
        child: Obx(() => Text("$count")),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () => count ++,
      ));
}
  1. 路由管理

    /// 全局配置路由及初始化路由
    return GetMaterialApp(
    ...
    getPages: PageManager.pages, /// 维护的所有页面
    initialRoute: RouteManager.splashPage, /// 初始化路由
    initialBinding: SplashBinding(), /// 初始化路由页面对应的binding
    ...
    );

    /// 带参数页面跳转
    Get.toNamed(RouteManager.tutorialPage, arguments: category);

    /// 参数获取
    @override
    void onInit() {
    super.onInit();
    if (Get.arguments is Category) {
    state.category = Get.arguments;
    state.title.value = state.category.chapterName ?? "";
    }
    }

  2. 主题管理

    /// 全局配置
    return GetMaterialApp(
    ...
    theme: ThemeData.light().copyWith(extensions: [lightColorData]), // 浅色主题
    darkTheme: ThemeData.dark().copyWith(extensions: [darkColorData]), // 深色主题
    ...
    );

    /// 需要动态切换
    Get.changeTheme(ThemeData.light().copyWith(extensions: [lightColorData]));

  3. 多语言管理:配合上述get_cli自动生成的多语言文本,结合getx实现多语言

    /// 全局配置语言,跟随系统
    @override
    Widget build(BuildContext context) {
    return GetMaterialApp(
    ...
    translationsKeys: translation.AppTranslation.translations, /// get_cli脚本生成的语言文本
    localizationsDelegates: const [
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
    ],
    supportedLocales: const [
    Locale('zh', 'CN'), /// 简体中文
    Locale('en', 'US'), /// 英文
    ], /// 支持的语言列表
    locale: Get.deviceLocale, /// 跟随手机系统语言
    fallbackLocale: const Locale('zh', 'CN'), /// 找不到指定语言时默认的语言(兜底)
    ...
    );
    }

    /// 需要动态切换
    var locale = Locale('en', 'US');
    Get.updateLocale(locale);

四、三方开源库使用(ps:flutter生态还是很好的,该有的开源库应有尽有)

bot_toast | Flutter package:基于该库实现全局loading

复制代码
/// 需要在app全局初始化
@override
Widget build(BuildContext context) {
  final botToastBuilder = BotToastInit();
  return GetMaterialApp(
    ...
    navigatorObservers: [
      BotToastNavigatorObserver(),
    ],
    builder: (BuildContext context, Widget? child) {
      return botToastBuilder(
          context,
          child:...);
    },
  );
}

/// 封装使用
CancelFunc showCommonLoading({
    String loadingText = "",
    Alignment? align = Alignment.center,
    crossPage = true,
    backButtonBehavior = BackButtonBehavior.ignore,
    bool clickClose = false,
    VoidCallback? onClose,
    Color? barrierColor,
    Color? backgroundColor,
    Color? circleColor,
    BoxConstraints? constraints,
    TextStyle? style,
  }) {
    return BotToast.showCustomLoading(
      align: align,
      onClose: onClose,
      clickClose: clickClose,
      backButtonBehavior: backButtonBehavior,
      crossPage: crossPage,
      backgroundColor: barrierColor ?? Colors.transparent,
      toastBuilder: (f) {
        return CommonLoading(
          loadingText: loadingText,
          backgroundColor: backgroundColor,
          circleColor: circleColor,
          constraints: constraints,
          style: style,
        );
      },
      animationDuration: const Duration(milliseconds: 250),
      animationReverseDuration: const Duration(milliseconds: 200),
    );
  }
}

oktoast | Flutter package:实现toast功能

复制代码
/// 需要在app初始化
@override
Widget build(BuildContext context) {
  return GetMaterialApp(
    builder: (BuildContext context, Widget? child) {
      return botToastBuilder(
          context,
          Material(
            elevation: 0,
            color: Colors.transparent,
            child: OKToast(
              child: child!,
            ),
          ));
    },
  );

/// 基本使用
showToast(LocaleKeys.username_hint.tr);

mmkv | Flutter package:本地持久化,应该大家都很熟悉啦~

event_bus | Dart package:全局事件监听

easy_refresh | Flutter package:下拉刷新上拉加载更多组件

webview_flutter | Flutter package:浏览器

相关推荐
太过平凡的小蚂蚁4 小时前
Android 版本特性完全解析:从6.0到16.0的实用指南
android
杨筱毅4 小时前
【底层机制】【Android】深入理解UI体系与绘制机制
android·底层机制
介一安全4 小时前
【Frida Android】基础篇8:Java层Hook基础——调用带对象参数的方法
android·网络安全·逆向·安全性测试·frida
puyaCheer4 小时前
Android 13 启动的时候会显示一下logo,很不友好
android·gitee
long_hai_d5 小时前
Aosp14桌面壁纸和锁屏壁纸的设置和加载分析
android
西西学代码6 小时前
Flutter---带输入框的对话框
flutter
_阿南_6 小时前
flutter在Xcode26打包的iOS26上全屏支持右滑的问题
flutter·ios·xcode
2501_916007476 小时前
iOS 26 软件性能测试 新版系统下评估全流程 + 多工具辅助方案
android·macos·ios·小程序·uni-app·cocoa·iphone
云霄IT6 小时前
绕过Frida检测反调试的一些办法
android·javascript