玩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 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台4 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone4 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc4 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo4 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077004 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼5 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone5 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen5 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone5 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui