Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Shared element Hero Animation not working with custom ModalRoute

Tags:

In order to get a Modal-Like effect in flutter (when a page is pushed on top the current page with a black background and transperent enough so you can see the page behind in the background).

i'm using a ModalRoute Class to show an overlay widget on top my current page.

my problem is : when my TestOverlay page enters, only the fadeIn animation is displayed but not the Shared Element Hero animation.

the page behind has a Hero(tag: "111", child: Text("Test")) widget and when im calling Navigator.of(context).push(TestOverlay()); only the FadeInis animated and the shared element transition does not work.. :(

anyone knows why?

Thanks!!

class TestOverlay extends ModalRoute<void> {
  TestOverlay();

  @override
  Duration get transitionDuration => Duration(milliseconds: 400);

  @override
  bool get opaque => false;

  @override
  bool get barrierDismissible => false;

  @override
  Color get barrierColor => Colors.black.withOpacity(0.7);

  @override
  String get barrierLabel => null;

  @override
  bool get maintainState => true;

  @override
  Widget buildPage(
      BuildContext context,
      Animation<double> animation,
      Animation<double> secondaryAnimation,
      ) {
    // This makes sure that text and other content follows the material style
    return Material(
      type: MaterialType.transparency,
      // make sure that the overlay content is not cut off
      child: GestureDetector(
        onTap: () {
          Navigator.pop(context);
        },
        behavior: HitTestBehavior.opaque,
        child: SafeArea(
          child: _buildOverlayContent(context),
        ),
      ),
    );
  }

  Widget _buildOverlayContent(BuildContext context) {
    return Center(
      child: Hero(tag: "111", Text("Test"))
    );
  }

  @override
  Widget buildTransitions(
      BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    // You can add your own animations for the overlay content
    return FadeTransition(
      opacity: animation,
      child: ScaleTransition(
        scale: animation,
        child: child,
      ),
    );
  }
}
like image 711
user2953680 Avatar asked Oct 06 '18 10:10

user2953680


1 Answers

Use PageRoute instead:

class TestOverlay extends PageRoute<void> {
  TestOverlay({
    @required this.builder,
    RouteSettings settings,
  })  : assert(builder != null),
        super(settings: settings);

  final WidgetBuilder builder;

  @override
  bool get opaque => false;

  @override
  Color get barrierColor => null;

  @override
  String get barrierLabel => null;

  @override
  bool get maintainState => true;

  @override
  Duration get transitionDuration => Duration(milliseconds: 350);

  @override
  Widget buildPage(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation) {
    final result = builder(context);
    return FadeTransition(
      opacity: Tween<double>(begin: 0, end: 1).animate(animation),
      child: result,
    );
  }
}
like image 81
Andrey Gordeev Avatar answered Oct 22 '22 05:10

Andrey Gordeev