Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import 'package:meta/meta.dart';
import 'package:flutter/material.dart';
abstract class RouteSetting {
List<Route> toInstance();
}
class Route<Arguments> {
final String name;
final bool initial;
final Widget Function(BuildContext context, Arguments args) builder;
const Route({
@required this.name,
@required this.builder,
this.initial,
});
}
class Router<T extends RouteSetting> {
final T setting;
final List<Route> routes;
Router(this.setting) : routes = setting.toInstance();
Route get initialRoute => routes.firstWhere((r) => r.initial == true);
Map<String, WidgetBuilder> toMaterialRoutes() => Map<String, WidgetBuilder>.fromIterable(
routes,
key: (dynamic route) => route.name as String,
value: (dynamic route) => (BuildContext context) {
// TODO: Builder widget?
final dynamic arg = ModalRoute.of(context).settings.arguments;
return route.builder(context, arg) as Widget;
},
);
/// Be aware!! You can pass a route which require argument without errors like below:
/// ```
/// ↓ Runtime error! because knowledge id is required
/// soeasyRoutes.pushWithoutArgument(context, (r) => r.comments);
/// ```
/// That's because [Route<void>] is able to override any kinda definition. Dartはクソ
Future<void> pushWithoutArgument<Ro extends Route<void>>(
BuildContext ctx,
Ro Function(T setting) fromSettingToName,
) {
final r = fromSettingToName(setting);
return Navigator.pushNamed(ctx, r.name);
}
Future<void> push<Arguments, Ro extends Route<Arguments>>(
BuildContext ctx,
Ro Function(T setting) fromSettingToName, {
@required Arguments arguments,
}) {
final r = fromSettingToName(setting);
return Navigator.pushNamed(ctx, r.name, arguments: arguments);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.