首页 前端知识 Flutter分模块开发、模块可单独启动、包含Provider

Flutter分模块开发、模块可单独启动、包含Provider

2025-02-24 13:02:46 前端知识 前端哥 768 307 我要收藏

前言

当前案例 Flutter SDK版本:3.22.2

  • 目前Flutter项目,很多都是在一个目录中,导致文件繁多,不利于维护,于是我尝试,创建不同目录进行模块开发,结果成功了,在此分享一下;

  • 项目中加入了一些常用操作

    • provider: 状态管理;
    • fluro: 路由管理;
    • 跨模块,读取静态资源:字体、图片;

效果图

结构图

方式一

1、创建根目录

新建一个空文件夹;

2、创建模块

在 flutter_module_develop 文件夹中,创建Flutter项目;

2.1、创建主模块

注意是Application类型,命名为app,这个命名大家随意;

2.2、创建子模块

注意是Package类型,commonhomeorderpersonal

3、建立依赖关系

  • 修改各个模块的 pubspec.yaml 文件,建立依赖关系;
  • 没有出现 循环依赖 的问题;

3.1、Common

name: common
description: "A new Flutter project."
publish_to: none
version: 0.0.1
homepage:

environment:
  sdk: '>=3.4.3 <4.0.0'
  flutter: ">=1.17.0"

dependencies:
  flutter:
    sdk: flutter
  app:
    path: ../app
  home:
    path: ../home
  order:
    path: ../order
  personal:
    path: ../personal
  provider: ^6.1.2
  fluro: ^2.0.5

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.0

flutter:
  assets:
    - assets/images/

  fonts:
    - family: Basteleur
      fonts:
        - asset: assets/fonts/Basteleur.ttf

3.2、Home

name: home
description: "A new Flutter project."
publish_to: none
version: 0.0.1
homepage:

environment:
  sdk: '>=3.4.3 <4.0.0'
  flutter: ">=1.17.0"

dependencies:
  flutter:
    sdk: flutter
  common:
    path: ../common

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.0

flutter:

  # To add assets to your package, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

3.3、Order

name: order
description: "A new Flutter project."
publish_to: none
version: 0.0.1
homepage:

environment:
  sdk: '>=3.4.3 <4.0.0'
  flutter: ">=1.17.0"

dependencies:
  flutter:
    sdk: flutter
  common:
    path: ../common

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.0

flutter:

  # To add assets to your package, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

3.4、Personal

name: personal
description: "A new Flutter project."
publish_to: none
version: 0.0.1
homepage:

environment:
  sdk: '>=3.4.3 <4.0.0'
  flutter: ">=1.17.0"

dependencies:
  flutter:
    sdk: flutter
  common:
    path: ../common

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.0

flutter:

  # To add assets to your package, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

3.5、App

name: app
description: "A new Flutter project."
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
  sdk: '>=3.4.3 <4.0.0'

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.6
  common:
    path: ../common

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.0

flutter:
  uses-material-design: true

路由配置

  • routers.dart
import 'package:app/page/main_index.dart';
import 'package:common/page/common_index.dart';
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
import 'package:home/page/home_index.dart';
import 'package:order/page/order_index.dart';
import 'package:personal/page/personal_index.dart';

class App {
  static const String root = '/';
}

class Common {
  static const String commonIndex = '/CommonIndex';
}

class Home {
  static const String homeIndex = '/HomeIndex';
}

class Order {
  static const String orderIndex = '/OrderIndex';
}

class Personal {
  static const String personalIndex = '/PersonalIndex';
}

class Routers {
  static FluroRouter router = FluroRouter();

  // 配置路由
  static void configureRouters() {
    router.notFoundHandler = Handler(handlerFunc: (_, __) {
      // 找不到路由时,返回指定提示页面
      return const Scaffold(
        body: Center(
          child: Icon(Icons.error),
        ),
      );
    });

    // 初始化路由
    _initRouter();
  }

  // 注册路由
  static _initRouter() {
    _initCommonIndex();
    _initOrderIndex();
    _initPersonalIndex();
    _initHomeIndex();
    _initRootIndex();
  }

  // 根页面
  static void _initRootIndex() {
    router.define(
      App.root,
      handler: Handler(
        handlerFunc: (_, __) => const MainIndex(),
      ),
    );
  }

  // 首页
  static void _initHomeIndex() {
    router.define(
      Home.homeIndex,
      handler: Handler(
        handlerFunc: (_, __) => const HomeIndex(),
      ),
    );
  }

  // 个人页面
  static void _initPersonalIndex() {
    router.define(
      Personal.personalIndex,
      handler: Handler(
        handlerFunc: (_, __) => const PersonalIndex(),
      ),
    );
  }

  // 订单页面
  static void _initOrderIndex() {
    router.define(
      Order.orderIndex,
      handler: Handler(
        handlerFunc: (_, __) => const OrderIndex(),
      ),
    );
  }

  // 公共页面
  static void _initCommonIndex() {
    router.define(
      Common.commonIndex,
      handler: Handler(
        handlerFunc: (_, __) => const CommonIndex(),
      ),
    );
  }

}
  • navigator_util.dart
import 'package:common/router/routers.dart';
import 'package:fluro/fluro.dart';
import 'package:flutter/cupertino.dart';

/// 路由工具类
/// 如果所在类没有 context,可以使用 全局context:navigatorKey.currentContext
class NavigatorUtil {

  /// 前往页面
  static Future<dynamic> push(
    BuildContext context,
    path, {
    bool replace = false, // 替换,进入新的页面时,将当前页面销毁
    bool clearStack = false, // 清空路由栈,进入新的页面时,其他实例的页面全部销毁
    Object? arguments, // 传递的参数
    TransitionType? transition, // 页面跳转的动画 类型
  }) {
    return Routers.router.navigateTo(
      context,
      path,
      replace: replace,
      clearStack: clearStack,
      transition: transition ?? TransitionType.inFromRight, // 默认跳转动画,从右侧进入
      routeSettings: RouteSettings(
        arguments: arguments,
      ),
    );
  }

}

Provider 

import 'package:flutter/material.dart';

class Counter extends ChangeNotifier {
  int count = 0;

  void compute() {
    count++;
    notifyListeners();
  }
}

// 使用
Consumer<Counter>(
    builder: (_,state,__) {
      return Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text('${state.count}'),
          IconButton(onPressed: () {
            state.compute();
          }, icon: const Icon(Icons.add)),
        ],
      );
    }
),

静态资源访问

  • 跨模块访问静态资源:要设置 package 属性;

    • package 属性的作用: 指定资源来自某个特定的包,最终访问的路径是 packages/<package_name>/<resource_path>
  • 比如当前图片,放在 common 模块,引用的时候,package属性的值就写 common;
    • Image.asset('assets/imgs/logo.png',package: 'common');
    • 最终访问的资源路径是:packages/common/assets/imgs/logo.png
  • 以下是支持 package 属性的主要组件或配置:

类别组件/配置是否支持 package 属性
图片加载Image.asset
图片加载AssetImage
字体加载TextStyle
字体加载RichText
主题配置ThemeData
自定义资源加载DefaultAssetBundle
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        fontFamily: 'Basteleur',
        package: PACKAGE_COMMON_NAME,
      ),
    );
  }

源码地址

https://github.com/youxia-mrhan/flutter_module_develop

方式二(模块独立启动)

  • 方式一 是以 app 主模块 为 Application 类型,子模块为 Package 类型,满足绝大多数场景,但子模块 不能独立运行。

  • 和方式一的区别:子模块 全部选择为 Application 类型,commonhomeorderpersonal,实现 模块独立启动

 

源码地址 

https://github.com/youxia-mrhan/flutter_module_develop2

注意事项

  • 当IDE找不到依赖包路径时,需要手动导包;
    • 比如IDE无法自动导入 import 'package:app/main/app.dart,那就手写;
  • 当一个模块发生了改变,比如 增删 操作,使用它的其他模块,必须 重新 pub get 同步一下,否则其他模块,使用的还是这个模块 之前的缓存

打包体积 

  • 两种方式的打包体积,是相同的;
cd app

flutter build apk

✓ Built build/app/outputs/flutter-apk/app-release.apk (18.9MB)

开发IDE推荐

  • 开发Flutter,用的比较多的IDE工具有:

    • Android StudioVisual Studio ScodeIntellij IDEA 等;
  • 推荐 Visual Studio Scode,这种分模块开发,会导致一些的IDE,无法进行断点调试,但 Visual Studio Scode 可以,它可以将多个目录,整合到一个工作区,非常强大;

    • 使用 Visual Studio Scode 直接打开 根目录 flutter_module_develop
    • 配置启动文件 launch.json; 

转载请注明出处或者链接地址:https://www.qianduange.cn//article/21095.html
标签
flutter
评论
发布的文章

C/C | 每日一练 (2)

2025-02-24 13:02:49

Linux性能监控工具汇总

2025-02-24 13:02:48

Python常见面试题的详解16

2025-02-24 13:02:48

QQ登录测试用例报告

2025-02-24 13:02:47

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!