如何在flutter中滑动到右侧新页面而不是底部?

问题描述 投票:0回答:4

将新页面转移到焦点的默认颤动动画是将其从底部向上滑动。如何更改此行为并从右侧或左侧滑动新页面?

      Navigator.push(
        context,
          new PageRouteBuilder(
          pageBuilder: (BuildContext context, _, __) {
            return new SearchView();
          }
          )
      );
dart material-design flutter flutter-layout
4个回答
24
投票

查看CupertinoPageRoute

用 iOS 过渡替换整个屏幕的模态路线。

页面从右侧滑入,反向退出。当另一页进入覆盖该页面时,该页面也会以视差向左移动。

页面从底部滑入,反向退出,全屏对话框无视差效果。

flutter gallery 示例应用程序中有一个演示:

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

13
投票

您可以创建一个带有您想要的动画的函数

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,
      );
    },
  );
}

每次推送到新屏幕时都会调用它

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

如果你想改变方向,你需要改变

begin
的偏移量 如果你想改变效果你需要改变
SlideTransition


0
投票
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)'),
      ),
    );
  }
}

这将创建一个带有过渡的两页路由,请参阅此处了解更多信息


0
投票

Matteo Antolini 答案的修改版本:

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);
  }
}

您可以将其复制+粘贴到文件中并在您的应用程序中使用它,例如:

onTap: () {

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

},

为了更好地理解页面滑动过渡,阅读官方文档

© www.soinside.com 2019 - 2024. All rights reserved.