上一篇分享了如何使用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进行封装:
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并实现prefix与getRoutePages:
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());
});
上面的代码只是注册了页面及相关路由,要让模块路由生效还需要在项目中注册:
在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…
希望对您有所帮助谢谢!!!