nylo-core / nylo

Nylo is the fastest way to build your next Flutter mobile app. Streamline your projects with Nylo's opinionated approach to building Flutter apps. Develop your next idea ⚡️
https://nylo.dev
MIT License
597 stars 61 forks source link

Hero image animations are not working #119

Closed OlrikNijmeijer closed 7 months ago

OlrikNijmeijer commented 7 months ago

I am trying to implement a Hero image, using the following instructions: https://api.flutter.dev/flutter/widgets/Hero-class.html

The problem i have with this when using the Nylo Framework, is that the animation only works when clicking on the back button. When using the navigation function "routeTo" or when using the original Navigator.push functions, the image does not animate into the new screen.

I figured out that when you don't navigate to a whole new page but just return a new scaffold, it does properly animate.

Below the code of my homepage

class HomePage extends NyStatefulWidget<HomeController> {
  static const path = '/home';

  HomePage({super.key}) : super(path, child: _HomePageState());
}

class _HomePageState extends NyState<HomePage> {
  @override
  Widget view(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Hello World".tr()),
        centerTitle: true,
        actions: [
          IconButton(
            onPressed: widget.controller.showAbout,
            icon: const Icon(Icons.info_outline),
          ),
        ],
      ),
      body: SafeAreaWidget(
        child: Center(
            child: Column(
          children: [
            GestureDetector(
              onTap: () {
                // THIS DOES NOT WORK PROPERLY
                // routeTo(SecondPage.path);

                // THIS DOES NOT WORK PROPERLY
                // Navigator.of(context).push(
                //   MaterialPageRoute<void>(
                //     builder: (BuildContext context) => SecondPage(),
                //   ),
                // );

                // THIS DOES WORK PROPERPLY
                // Navigator.of(context).push(MaterialPageRoute<void>(
                //   builder: (BuildContext context) => Scaffold(
                //     appBar: AppBar(
                //       title: const Text('Second Page'),
                //     ),
                //     body: Center(
                //       child: Hero(
                //           tag: 'square-img',
                //           child: Image.network(
                //             "https://nylo.dev/images/nylo_logo_filled.png",
                //             height: 200,
                //           )),
                //     ),
                //   ),
                // ));
              },
              child: Hero(
                  tag: 'square-img',
                  child: Image.network(
                    "https://nylo.dev/images/nylo_logo_filled.png",
                    height: 100,
                  )),
            )
          ],
        )),
      ),
    );
  }
}

Below the code of my second page

class _SecondPageState extends NyState<SecondPage> {
  @override
  init() async {}

  @override
  Widget view(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Second")),
      body: SafeArea(
        child: Center(
          child: Container(
            child: Hero(
                tag: 'square-img',
                child: Image.network(
                    "https://nylo.dev/images/nylo_logo_filled.png",
                    height: 200)),
          ),
        ),
      ),
    );
  }
}

In the code of the homepage I provided 3 ways of navigating. The first or second should work but doesn't. The third part is not something that is works when you build a large app.

Hopefully there is a way to fix this issue.

agordn52 commented 7 months ago

Hi @OlrikNijmeijer,

As per the documentation, you need to use the Navigator.of(context).push method to use the Hero widget.

Navigator.of(context).push(MaterialPageRoute<void>(
      builder: (BuildContext context) => Scaffold(
        appBar: AppBar(
          title: const Text('Second Page'),
        ),
        body: const Center(
          child: Hero(
            tag: 'hero-rectangle',
            child: BoxWidget(size: Size(200.0, 200.0)),
          ),
        ),
      ),
    ));
  }

Using routeTo will not work.

However, you can do this.

Navigator.of(context).push(MaterialPageRoute<void>(
    builder: (BuildContext context) {
       return SecondPage();
    },
));

// please ensure that your page uses `build` instead of `view` like in the below example

class SecondPage extends NyStatefulWidget {
  static const path = '/second';

  SecondPage({super.key}) : super(path, child: _SecondPageState());
}

class _SecondPageState extends NyState<SecondPage> {

  @override
  Widget build(BuildContext context) {
   ...
  }

Hope that helps 👍

OlrikNijmeijer commented 7 months ago

@agordn52 Thanks for the reply! Changing the override on the view to build fixed the issue for me. I created the pages using the metro make:page commands, that's why it was an override on view instead of build.