jia chen
jia chen

Reputation: 760

How to slide to new page on the right instead of the bottom in flutter?

The default flutter animation to transit a new page into the focus is to slide it up from the bottom. How do i change this behaviors and slide the new page in from the right or left instead?

      Navigator.push(
        context,
          new PageRouteBuilder(
          pageBuilder: (BuildContext context, _, __) {
            return new SearchView();
          }
          )
      );

Upvotes: 19

Views: 26159

Answers (4)

Fathi Dev
Fathi Dev

Reputation: 179

A modified version of Matteo Antolini's answer:

import 'package:flutter/material.dart';

class ScreenNavigator {
  final BuildContext cx;
  ScreenNavigator({
    required this.cx,
  });
  navigate(Widget page, Tween<Offset> tween) {
    Navigator.push(
      cx,
      PageRouteBuilder(
        pageBuilder: (context, animation, secondaryAnimation) {
          return page;
        },
        transitionDuration: Durations.long1,
        transitionsBuilder: (context, animation, secondaryAnimation, child) {
          // create CurveTween
          const Curve curve = Curves.ease;
          final CurveTween curveTween = CurveTween(curve: curve);
          // chain Tween with CurveTween
          final Animatable<Offset> chainedTween = tween.chain(curveTween);
          final Animation<Offset> offsetAnimation =
              animation.drive(chainedTween);
          return SlideTransition(position: offsetAnimation, child: child);
        },
      ),
    );
  }
}

class NavigatorTweens {
  static Tween<Offset> bottomToTop() {
    const Offset begin = Offset(0.0, 1.0);
    const Offset end = Offset(0.0, 0.0);
    return Tween(begin: begin, end: end);
  }

  static Tween<Offset> topToBottom() {
    const Offset begin = Offset(0.0, -1.0);
    const Offset end = Offset(0.0, 0.0);
    return Tween(begin: begin, end: end);
  }

  static Tween<Offset> leftToRight() {
    const Offset begin = Offset(-1.0, 0.0);
    const Offset end = Offset(0.0, 0.0);
    return Tween(begin: begin, end: end);
  }

  static Tween<Offset> rightToLeft() {
    const Offset begin = Offset(1.0, 0.0);
    const Offset end = Offset(0.0, 0.0);
    return Tween(begin: begin, end: end);
  }
}

you can copy+paste it in a file and use it across your app like:

onTap: () {

   ScreenNavigator(cx: context)
   .navigate(Page(),NavigatorTweens.leftToRight());

},

to have better understanding of page sliding transition, read the official document

Upvotes: 0

A5H1Q
A5H1Q

Reputation: 624

import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      home: Page1(),
    ),
  );
}

class Page1 extends StatelessWidget {
  const Page1({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.of(context).push(_createRoute());
          },
          child: const Text('Open Page Two'),
        ),
      ),
    );
  }
}

Route _createRoute() {
  return PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) => const Page2(),
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      const begin = Offset(1.0, 0.0);
      const end = Offset.zero;
      const curve = Curves.ease;

      var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));

      return SlideTransition(
        position: animation.drive(tween),
        child: child,
      );
    },
  );
}

class Page2 extends StatelessWidget {
  const Page2({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: const Center(
        child: Text('Hi, This is Page Two! (slided-In from Right)'),
      ),
    );
  }
}

This creates a two page route with transitions, see here for more info

Upvotes: 0

Matteo Antolini
Matteo Antolini

Reputation: 3068

You can create a function with your desirable animation

Route createRoute(Widget page) {
  return PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) => page,
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      const begin = Offset(1.0, 0.0);
      const end = Offset.zero;
      const curve = Curves.ease;

      var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));

      return SlideTransition(
        position: animation.drive(tween),
        child: child,
      );
    },
  );
}

And call it each time you push to a new screen

Navigator.of(context).push(createRoute(SearchView()))

If you want to change the direction you need to change the offset of begin If you want to change the effect you need to change SlideTransition

Upvotes: 15

Danny Tuppeny
Danny Tuppeny

Reputation: 42383

Check out the CupertinoPageRoute:

A modal route that replaces the entire screen with an iOS transition.

The page slides in from the right and exits in reverse. The page also shifts to the left in parallax when another page enters to cover it.

The page slides in from the bottom and exits in reverse with no parallax effect for fullscreen dialogs.

There's a demo of it in the flutter gallery example app:

Navigator.of(context, rootNavigator: true).push(
  new CupertinoPageRoute<bool>(
    fullscreenDialog: true,
    builder: (BuildContext context) => new Tab3Dialog(),
  ),
);

Upvotes: 25

Related Questions