Flutter中使用GetX从0到1搭建自已的项目框架(二)

1,651 阅读1分钟

上一篇分享了如何使用GetX从0到1搭建自已的项目框架,在example中如何引用flutter_eden(对Getx进行封装),在example/main.dart中引用EdenMaterialWrapper

void main() {
  runApp(
    EdenMaterialWrapper(
      logTag: "Example",
      enableLog: true,
      initialRoute: Routes.app.root,
      unknownRoute: Routes.app.unknownRoute,
      getPages: Routes.getPages(),
      theme: EdenThemeData.lightThemeData(),
      initialBinding: ServiceBindings(),
      splashBuilder: (context, child) {
        // final botToastBuilder = BotToastInit();
        // child = botToastBuilder(context, child);

        return FutureBuilder<void>(
          key: const ValueKey('initFuture'),
          future: Get.find<SplashService>().init(),
          builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
            print("snapshot=${snapshot.connectionState}");
            if (snapshot.connectionState == ConnectionState.done) {
              return child ?? const SizedBox.shrink();
            }
            return SplashView();
          },
        );
      },
    ),
  );
  EdenThemeData.systemUiOverlay();
}

接下来我们来看一下initialRoute: Routes.app.root都做了哪些封装:

在flutter_eden中对Route进行封装:

image.png

EdenBaseRoute 对GetX的 GetPage进行了封装,并实现了BaseRoute

abstract class EdenBaseRoute implements BaseRoute {
  ///
  GetPage routePage<T>({
    required String name,
    required GetPageBuilder page,
    required Function bindingsBuilder,
    List<Bindings>? bindings,
    bool? preventDuplicates,
    List<GetMiddleware>? middlewares,
    List<GetPage<dynamic>>? children,
    Transition? transition,
  }) {
    return GetPage<T>(
      name: name,
      page: page,
      preventDuplicates: preventDuplicates ?? true,
      binding: BindingsBuilder(() {
        bindingsBuilder();
      }),
      bindings: bindings ?? [],
      middlewares: middlewares,
      children: children ?? [],
      transition: transition ?? Transition.cupertino,
    );
  }

  S edenFind<S>({String? tag}) => Get.find<S>(tag: tag);

  ///
  void edenLazyPut<S>(InstanceBuilderCallback<S> builder,
      {String? tag, bool fenix = false}) {
    Get.lazyPut<S>(builder, tag: tag, fenix: fenix);
  }
}

BaseRoute中定义了一个路由前缀prefix和一个Getpage 数组List<GetPage> getRoutePages()

abstract class BaseRoute {
  ///prefix
  String get prefix;

  ///Getpage
  List<GetPage> getRoutePages();
}

在example中继承EdenBaseRoute并实现prefixgetRoutePages:

class AppRoute extends EdenBaseRoute {
  @override
  String get prefix => "/app";

  String get root => "/root";

  String get home => prefix + "/home";
  String get message => prefix + "/message";
  String get account => prefix + "/account";

  ///
  String get login => prefix + "/login";
  String get accountProfile => prefix + "/account/profile";
  String get proxy => prefix + "/proxy";

  /// 找不到页面
  String get error404 => prefix + "/error/unknown404";

  GetPage get unknownRoute => routePage(
      name: error404,
      page: () => ErrorPage(),
      bindingsBuilder: () {
        Get.lazyPut(() => ErrorController());
      });
  @override
  List<GetPage> getRoutePages() {
    return [
      routePage(
        name: root,
        page: () => AppComponent(),
        bindings: [
          AppBindings(),
        ],
        // middlewares: [AuthMiddleware(priority: 0)],
        bindingsBuilder: () {
          // Get.lazyPut(() => AppController());
        },
        children: [
          routePage(
            name: home,
            page: () => HomeIndex(),
            bindingsBuilder: () {
              // Get.lazyPut(() => HomeController());
            },
          ),
          routePage(
            name: message,
            page: () => MessagePage(),
            bindingsBuilder: () {
              // Get.lazyPut(() => MessageController());
            },
          ),
          routePage(
            name: account,
            page: () => AccountPage(),
            bindingsBuilder: () {},
          ),
        ],
      ),
      routePage(
        name: proxy,
        page: () => ProxySettingPage(),
        bindingsBuilder: () {},
      ),

      /// login
      routePage(
        name: login,
        page: () => LoginPage(),
        bindingsBuilder: () {
          //dao
          Get.lazyPut<ILoginProvider>(() => LoginProvider());

          //service
          Get.lazyPut<ILoginRespository>(
              () => LoginRespositoryImpl(provider: Get.find()));
          //controller
          Get.lazyPut(() => LoginController(loginRespository: Get.find()));
        },
      ),
      //profile
      routePage(
        name: accountProfile,
        page: () => ProfilePage(),
        bindingsBuilder: () {
          Get.lazyPut(() => ProfileController());
        },
      ),
      routePage(
          name: error404,
          page: () => ErrorPage(),
          bindingsBuilder: () {
            Get.lazyPut(() => ErrorController());
          })
    ];
  }
}

EdenRoute 对Get的路由跳转进行封装:

class EdenRoute {
  EdenRoute._();

  /// 打开新页面
  static Future<T?> push<T>(
    /// 页面路径
    String path, {

    /// 参数
    Map<String, String>? parameters,

    /// arguments
    dynamic arguments,
    bool preventDuplicates = true,
  }) async {
    // 整理参数
    // 输出URL

    return Get.toNamed<T>(
      path,
      parameters: parameters,
      arguments: arguments,
      preventDuplicates: preventDuplicates,
    );
  }

  /// offAndToNamed
  static Future<T?> offAndToNamed<T>(
    String path, {
    Map<String, String>? parameters,
    dynamic arguments,
  }) async {
    // 整理参数
    // 输出URL
    return Get.offAndToNamed<T>(
      path,
      parameters: parameters,
      arguments: arguments,
    );
  }

  static Future<T?> offAllToNamed<T>(
    String path, {
    Map<String, String>? parameters,
    dynamic arguments,
  }) async {
    // 整理参数
    // 输出URL
    return Get.offAllNamed<T>(
      path,
      parameters: parameters,
      arguments: arguments,
    );
  }

  /// 打开新页面,参数是页面实例
  static Future<T?>? to<T>(
    dynamic page, {
    dynamic arguments,
    Bindings? binding,
    bool preventDuplicates = true,
  }) {
    return Get.to<T>(
      page,
      arguments: arguments,
      binding: binding,
      preventDuplicates: preventDuplicates,
      transition: Transition.cupertino,
    );
  }

  static void back<T>({
    T? result,
    closeOverlays = false,
  }) {
    Get.back<T>(
      result: result,
      closeOverlays: closeOverlays,
    );
  }

  static void until<T>(
    String rootName,
  ) {
    Get.until((route) => Get.currentRoute == rootName);
  }
}

通过EdenRoute.push()进行页面跳转:

EdenRoute.push(Routes.app.account);

如果EdenRoute.push()一个没有注册的路由则会自动跳转到404页面: unknownRoute: Routes.app.unknownRoute

 GetPage get unknownRoute => routePage(
      name: error404,
      page: () => ErrorPage(),
      bindingsBuilder: () {
        Get.lazyPut(() => ErrorController());
      });

上面的代码只是注册了页面及相关路由,要让模块路由生效还需要在项目中注册:

image.png

example/routes/routes.dart中注册模块路由AppRoute

abstract class Routes {
  static final app = AppRoute();
  static final eden = EdenModuleRoute();
  static final component = ComponentRoute();
  static List<GetPage> getPages() {
    return [
      ...eden.getRoutePages(),
      ...app.getRoutePages(),
      ...component.getRoutePages(),
    ];
  }
}

example/main.dart 注册getPages: Routes.getPages()

 void main() {
  runApp(
    EdenMaterialWrapper(
      logTag: "Example",
      enableLog: true,
      initialRoute: Routes.app.root,
      unknownRoute: Routes.app.unknownRoute,
      getPages: Routes.getPages(),
      theme: EdenThemeData.lightThemeData(),
      initialBinding: ServiceBindings(),
      splashBuilder: (context, child) {
        // final botToastBuilder = BotToastInit();
        // child = botToastBuilder(context, child);

        return FutureBuilder<void>(
          key: const ValueKey('initFuture'),
          future: Get.find<SplashService>().init(),
          builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
            print("snapshot=${snapshot.connectionState}");
            if (snapshot.connectionState == ConnectionState.done) {
              return child ?? const SizedBox.shrink();
            }
            return SplashView();
          },
        );
      },
    ),
  );
  EdenThemeData.systemUiOverlay();
}

通过上面对路由的配置便可以轻松的使用扩展自已的应用了。

由于篇幅原因今天就分享到这里,后续会连载!

如果您对此项目感兴趣可以加入一起维护开发!

开源项目地址:github.com/rebelning/f…

希望对您有所帮助谢谢!!!