How to implement custom page transition with animation when navigate from one page to another?

Viewed 112

I want to achieve below custom animation when navigation from one page to another i am trying with hero animation but no luck any help will appreciated. Thanks! Here is gif, which i want to implement

1 Answers

I'd take look at this doc https://docs.flutter.dev/cookbook/animation/page-route-animation first.

I'd propose a mix between example shown there of slide-in transition where new page slides from the bottom in your example and mix it with fade-in transition shown here:

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

import 'main.dart';

class FadeAnimation extends StatelessWidget {
  static const routeName = 'Fade_Animation';
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Fade Animation"),
      ),
      body: ListView.builder(
          itemCount: curveList.length,
          itemBuilder: (context, index) {
            return Card(
              child: ListTile(
                title: Text("${curveList[index]}"),
                leading: CircleAvatar(
                  child: Text("${index + 1}"),
                  backgroundColor: Colors.white,
                ),
                onTap: () {
                  print(curveList.length);
                  Navigator.of(context).push(PageRouteBuilder(
                      pageBuilder: (context, animation, anotherAnimation) {
                        return ReturnPage();
                      },
                      transitionDuration: Duration(milliseconds: 2000),
                      transitionsBuilder:
                          (context, animation, anotherAnimation, child) {
                        animation = CurvedAnimation(
                            curve: curveList[index], parent: animation);
                        return FadeTransition(
                          opacity:animation,
                          child: child,
                        );
                      }));
                },
              ),
            );
          }),
    );
  }
}

The list.dart file:

import 'package:flutter/animation.dart';


List<Curve> curveList = [
  Curves.bounceIn,
  Curves.bounceInOut,
  Curves.bounceOut,
  Curves.decelerate,
  Curves.ease,
  Curves.easeIn,
  Curves.easeInBack,
  Curves.easeInCirc,
  Curves.easeInCubic,
  Curves.easeInExpo,
  Curves.easeInOut,
  Curves.easeInOutBack,
  Curves.easeInOutCirc,
  Curves.easeInOutCubic,
  Curves.easeInOutExpo,
  Curves.easeInOutQuad,
  Curves.easeInOutQuart,
  Curves.easeInOutQuint,
  Curves.easeInOutSine,
  Curves.easeInQuad,
  Curves.easeInQuart,
  Curves.easeInQuint,
  Curves.easeInSine,
  Curves.easeInToLinear,
  Curves.easeOut,
  Curves.easeOutBack,
  Curves.easeOutCubic,
  Curves.easeOutExpo,
  Curves.easeOutQuad,
  Curves.easeOutQuart,
  Curves.easeOutQuint,
  Curves.easeOutSine,
  Curves.elasticIn,
  Curves.elasticInOut,
  Curves.elasticOut,
  Curves.fastLinearToSlowEaseIn,
  Curves.fastOutSlowIn,
  Curves.linear,
  Curves.linearToEaseOut,
  Curves.slowMiddle,
];

Combination of the two should be exactly what you're looking for.

main.dart file:

import 'package:flutter/material.dart';

import 'fadeAnimation.dart';


main() {
  runApp(MaterialApp(
    routes: {
      FadeAnimation.routeName: (context) => FadeAnimation(),
    },
    theme: ThemeData.dark(),
    debugShowCheckedModeBanner: false,
    home: SafeArea(
      child: Scaffold(
        appBar: AppBar(title: Text("Page Tranaction")),
        body: ListView.builder(
          itemBuilder: (context, index) {
            return Padding(
              padding: const EdgeInsets.all(8.0),
              child: Card(
                child: ListTile(
                  onTap: () {
                    Navigator.of(context).pushNamed(animationTypeList[index]);
                  },
                  leading: CircleAvatar(
                    backgroundColor: Colors.white,
                    child: Text("${index + 1}"),
                  ),
                  title: Text(animationTypeList[index].toString()),
                ),
              ),
            );
          },
          itemCount: animationTypeList.length,
        ),
      ),
    ),
  ));
}

class ReturnPage extends StatelessWidget {
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Text('you're here'),
      ),
    );
  }
}

var animationTypeList = [
  FadeAnimation.routeName,
];

Or instead of combining the 2 during transition wrap widget that contains the next screen with fade-in widget so when it gets created it fades in only once with some internal variable keeping track of that. That way you would have for example: slide-in animation during transition and widget you're transiting to would be opaque at first with gradual fade-in. Or the other way around.

Hope this helps!

Related