sailor 0.7.1
sailor: ^0.7.1 copied to clipboard

Easily manage page navigation/routing in Flutter apps. Add page transition animations, log navigation events.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:sailor/sailor.dart';

void main() async {
  Routes.createRoutes();
  runApp(App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Compass Example',
      home: Home(),
      onGenerateRoute: Routes.sailor.generator(),
      navigatorKey: Routes.sailor.navigatorKey,
      navigatorObservers: [
        SailorLoggingObserver(),
        Routes.sailor.navigationStackObserver,
      ],
    );
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Page'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            RaisedButton(
              child: Text('Open Second Page'),
              onPressed: () async {
                final response = await Routes.sailor.navigate<bool>(
                  "/secondPage",
                  transitions: [
                    SailorTransition.slide_from_top,
                  ],
                  customTransition: MyCustomTransition(),
                  params: {
                    'id': null,
                  },
                );

                print("Response from SecondPage: $response");
              },
            ),
            RaisedButton(
              child: Text('Open Multi Page (Second and Third)'),
              onPressed: () async {
                final responses = await Routes.sailor.navigateMultiple([
                  RouteArgsPair(
                    "/secondPage",
                    args: SecondPageArgs("Multi Page!"),
                  ),
                  RouteArgsPair(
                    "/thirdPage",
                    args: ThirdPageArgs(10),
                  ),
                  RouteArgsPair("/pushReplacePage"),
                ]);

                print("Second Page Response ${responses[0]}");
                print("Third Page Response ${responses[1]}");
                print("Third Page Response ${responses[2]}");
              },
            ),
            RaisedButton(
              child: Text('Push Replace Page'),
              onPressed: () async {
                Routes.sailor.navigate("/pushReplacePage");
              },
            ),
            RaisedButton(
              child: Text('Print navigation stack!'),
              onPressed: () {
                Routes.sailor.navigationStackObserver.prettyPrintStack();
              },
            ),
            RaisedButton(
              child: Text('Push Replace Page'),
              onPressed: () async {
                Routes.sailor.navigate("/pushReplacePage");
              },
            ),
            RaisedButton(
              child: Text('Push Replace Page'),
              onPressed: () async {
                Routes.sailor.navigate("/pushReplacePage");
              },
            ),
            RaisedButton(
              child: Text('Print navigation stack!'),
              onPressed: () {
                Routes.sailor.navigationStackObserver.prettyPrintStack();
              },
            ),
          ],
        ),
      ),
    );
  }
}

class SecondPageArgs extends BaseArguments {
  final String text;

  SecondPageArgs(this.text) : assert(text != null);
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final args = Sailor.args<SecondPageArgs>(context);
    final id = Sailor.param<int>(context, 'id');

    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text(args?.text ?? 'Second Page'),
            Text("Param('id'): $id"),
            RaisedButton(
              child: Text('Close Page'),
              onPressed: () {
                Routes.sailor.pop(true);
              },
            ),
            RaisedButton(
              child: Text('Print navigation stack!'),
              onPressed: () {
                Routes.sailor.navigationStackObserver.prettyPrintStack();
              },
            ),
          ],
        ),
      ),
    );
  }
}

class ThirdPageArgs extends BaseArguments {
  final int count;

  ThirdPageArgs(this.count);
}

class ThirdPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final args = Sailor.args<ThirdPageArgs>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Third Page'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text("Count from args is :${args?.count}"),
            RaisedButton(
              child: Text('Close Page'),
              onPressed: () {
                Routes.sailor.pop(10);
              },
            ),
            RaisedButton(
              child: Text('Print navigation stack!'),
              onPressed: () {
                Routes.sailor.navigationStackObserver.prettyPrintStack();
              },
            ),
          ],
        ),
      ),
    );
  }
}

class PushReplacePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Third Page'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            RaisedButton(
              child: Text('Push Replace'),
              onPressed: () {
                Routes.sailor.navigate(
                  "/secondPage",
                  navigationType: NavigationType.pushReplace,
                );
              },
            ),
            RaisedButton(
              child: Text('Push Unitl First and Replace'),
              onPressed: () {
                Routes.sailor.navigate(
                  "/thirdPage",
                  navigationType: NavigationType.pushAndRemoveUntil,
                  removeUntilPredicate: (route) => route.isFirst,
                );
              },
            ),
            RaisedButton(
              child: Text('Print navigation stack!'),
              onPressed: () {
                Routes.sailor.navigationStackObserver.prettyPrintStack();
              },
            ),
            Text(Routes.sailor.navigationStackObserver
                .getRouteStack()[0]
                .toString())
          ],
        ),
      ),
    );
  }
}

class Routes {
  static final sailor = Sailor(
    options: SailorOptions(
      handleNameNotFoundUI: true,
      isLoggingEnabled: true,
      customTransition: MyCustomTransition(),
      defaultTransitions: [
        SailorTransition.slide_from_bottom,
        SailorTransition.zoom_in,
      ],
      defaultTransitionCurve: Curves.decelerate,
      defaultTransitionDuration: Duration(milliseconds: 500),
    ),
  );

  static void createRoutes() {
    sailor.addRoutes(
      [
        SailorRoute(
          name: "/secondPage",
          builder: (context, args, params) => SecondPage(),
          defaultArgs: SecondPageArgs('From default arguments!'),
          customTransition: MyCustomTransition(),
          params: [
            SailorParam<String>(
              name: 'id',
            ),
          ],
          defaultTransitions: [
            SailorTransition.slide_from_bottom,
            SailorTransition.zoom_in,
          ],
          routeGuards: [
            SailorRouteGuard.simple((context, args, params) async {
              return true;
            }),
            CustomRouteGuard(),
          ],
        ),
        SailorRoute(
          name: "/thirdPage",
          builder: (context, args, params) => ThirdPage(),
          defaultTransitions: [SailorTransition.slide_from_left],
        ),
        SailorRoute(
          name: "/pushReplacePage",
          builder: (context, args, params) => PushReplacePage(),
          routeGuards: [
            SailorRouteGuard.simple(
              (context, args, params) => Future.value(true),
            )
          ],
        ),
      ],
    );
  }
}

class MyCustomTransition extends CustomSailorTransition {
  @override
  Widget buildTransition(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
    Widget child,
  ) {
    return FadeTransition(
      opacity: animation,
      child: child,
    );
  }
}

class CustomRouteGuard extends SailorRouteGuard {
  @override
  Future<bool> canOpen(
    BuildContext context,
    BaseArguments args,
    ParamMap paramMap,
  ) async {
    return false;
  }
}
120
likes
100
pub points
87%
popularity

Easily manage page navigation/routing in Flutter apps. Add page transition animations, log navigation events.

Homepage

Documentation

API reference

License

MIT (LICENSE)

Dependencies

flutter

More

Packages that depend on sailor