Skip to content

Instantly share code, notes, and snippets.

@HansMuller
Created August 3, 2018 17:12
Show Gist options
  • Select an option

  • Save HansMuller/f4a86fc31fdbc9699e1bd4947e9b15fd to your computer and use it in GitHub Desktop.

Select an option

Save HansMuller/f4a86fc31fdbc9699e1bd4947e9b15fd to your computer and use it in GitHub Desktop.

Revisions

  1. Hans Muller created this gist Aug 3, 2018.
    121 changes: 121 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,121 @@
    // popModal() support for Navigator
    // https://github.com/flutter/flutter/issues/16677

    // If app pushes a new route from a modal route (such as full screen
    // dialog), closing the modal starts all exit animations at the same
    // time leading to an odd transition.
    //
    // Expected behavior is for the close action to execute a single modal
    // exit animation and apply this animation only on the last route
    // visible. In the example above, the secondary route would disappear
    // from view revealing the entry route via the full screen dialog exit
    // animation.
    //
    // It is worth noting that if second route pushes a third route,
    // normal MaterialPageRoute animations should be executed (both entry
    // and exit). The only difference between this and current behavior is
    // when the app wants to close the entire modal path (modal + all
    // pages that opened from that modal).
    //
    // Suggested sequence:
    // - Remove all routes between current route and modal route (including modal route).
    // - Modify the exit animation of the current route.
    // - Pop the current route.


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

    void main() {
    runApp(new MyApp());
    }

    class MyApp extends StatelessWidget {
    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
    return new MaterialApp(
    debugShowCheckedModeBanner: false,
    title: 'Flutter Demo',
    theme: new ThemeData(
    primarySwatch: Colors.blue,
    ),
    home: new Page('First'),
    );
    }
    }

    class Page extends StatelessWidget {
    final String title;

    const Page(this.title);

    @override
    Widget build(BuildContext context) {
    timeDilation = 10.0;

    return new Scaffold(
    appBar: new AppBar(
    title: new Text(title),
    ),
    body: new Center(
    child: new RaisedButton(
    onPressed: () {
    final Route modalRoute = new MaterialPageRoute(
    settings: new RouteSettings(name: 'Modal'),
    fullscreenDialog: true,
    builder: (context) => new ModalPage(),
    );
    Navigator.push(context, modalRoute);
    },
    child: new Text('Launch Modal'),
    ),
    ),
    );
    }
    }

    class ModalPage extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return new Scaffold(
    appBar: new AppBar(
    title: new Text('Modal Page'),
    ),
    body: new Center(
    child: new RaisedButton(
    onPressed: () {
    final Route secondaryRoute = new MaterialPageRoute(
    settings: new RouteSettings(name: 'Secondary'),
    builder: (BuildContext context) => new SecondaryPage(),
    );
    Navigator.push(context, secondaryRoute);
    },
    child: new Text('Launch Secondary Page'),
    ),
    ),
    );
    }
    }

    class SecondaryPage extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return new Scaffold(
    appBar: new AppBar(title: new Text('Secondary Page')),
    body: new Center(
    child: new RaisedButton(
    onPressed: () {
    if (ModalRoute.of(context).animation.isCompleted) {
    Navigator.removeRouteBelow(context, ModalRoute.of(context));
    Navigator.pop(context);
    } else {
    Navigator.popUntil(context, ModalRoute.withName('/'));
    }
    },
    child: new Text('Clear All'),
    ),
    ),
    );
    }
    }