滑动返回手势Flutter

17

我如何在Flutter中实现从左侧滑动返回的手势?不确定它是否已经自动实现了iOS,但我也想在Android上实现(因为事情正在变得基于手势)。


2
请问如何在Flutter中实现向前滑动到上一页? - najeira
@najeira 谢谢,我会关闭这个! - Tom O'Sullivan
7个回答

11

使用 CupertinoPageRoute 可以使其在 Android 上正常工作;

import 'package:flutter/cupertino.dart';

(如在此处所回答的)


3
你可以将Theme.platform设置为TargetPlatform.ios。这将使得在每个设备上都使用滑动返回手势。

3

您可以像Tom O'Sullivan上面说的那样使用CupertinoPageRoute()

然而,如果您想要自定义它(例如使用自定义转换持续时间),则可以使用PageRouteBuilder并获得相同的向右滑动手势来返回。 这时需要重写buildTransitions()

对于iOS,默认的PageTransitionBuilderCupertinoPageTransitionsBuilder()。 因此,我们可以在buildTransitions()中使用它。这会自动给我们提供向右滑动以返回上一页的手势。

下面是CustomPageRouteBuilder的一些示例代码:

class CustomPageRouteBuilder<T> extends PageRoute<T> {
  final RoutePageBuilder pageBuilder;
  final PageTransitionsBuilder matchingBuilder = const CupertinoPageTransitionsBuilder(); // Default iOS/macOS (to get the swipe right to go back gesture)
  // final PageTransitionsBuilder matchingBuilder = const FadeUpwardsPageTransitionsBuilder(); // Default Android/Linux/Windows

  CustomPageRouteBuilder({this.pageBuilder});

  @override
  Color get barrierColor => null;

  @override
  String get barrierLabel => null;

  @override
  Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
    return pageBuilder(context, animation, secondaryAnimation);
  }

  @override
  bool get maintainState => true;

  @override
  Duration get transitionDuration => Duration(milliseconds: 900); // Can give custom Duration, unlike in MaterialPageRoute

  @override
  Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    return matchingBuilder.buildTransitions<T>(this, context, animation, secondaryAnimation, child);
  }
}

然后要去到一个新页面:

GestureDetector(
  onTap: () => Navigator.push(
    context,
    CustomPageRouteBuilder(pageBuilder: (context, animation, secondaryAnimation) => NewScreen()),
  ),
  child: ...,
)

过渡时间怎么样:transitionDuration和反向过渡时间:transitionDuration,参数?你能否编辑你的答案以包括这些参数? - Yogi Arif Widodo
@override // TODO: 实现 reverseTransitionDuration 方法 Duration get reverseTransitionDuration => const Duration(milliseconds: 900); - Yogi Arif Widodo
这对我非常有效,应该是正确的答案!当您创建自定义页面路由时会很有帮助。 - scugn1zz0

3
您可以将您的主题(和darkTheme)的平台设置为TargetPlatform.iOS,您可以将您的主题的pageTransitionsTheme设置为,
pageTransitionsTheme: PageTransitionsTheme(
    builders: {
      TargetPlatform.android: CupertinoPageTransitionsBuilder(),
      TargetPlatform.iOS: CupertinoPageTransitionsBuilder(),
    },
),

您可以使用 CupertinoPageRoute 加载新页面...但在确保使用 Navigator.push(而不是 Navigator.pushReplacement)到达新屏幕之前,这些都不会起作用!希望这能帮助那些正在处理现有转换并没有注意到这个关键细节的人。:)


0

使用这个插件:

https://pub.dev/packages/cupertino_back_gesture

一个Flutter包,用于设置iOS返回滑动手势区域的自定义宽度。 基本使用方法如下:
import 'package:cupertino_back_gesture/cupertino_back_gesture.dart';

BackGestureWidthTheme(
 backGestureWidth: BackGestureWidth.fraction(1 / 2),
  child: MaterialApp(
    theme: ThemeData(
      pageTransitionsTheme: PageTransitionsTheme(
        builders: {
           //this is default transition
          //TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(),
          //You can set iOS transition on Andoroid
          TargetPlatform.android: CupertinoPageTransitionsBuilderCustomBackGestureWidth(),
          TargetPlatform.iOS: CupertinoPageTransitionsBuilderCustomBackGestureWidth(),
        },
      ),
    ),
    home: MainPage(),
  ),
)

插件页面上有更多详细信息


目前你的回答不够清晰。请编辑并添加更多细节,以帮助其他人理解它如何回答所提出的问题。你可以在帮助中心找到有关如何撰写好答案的更多信息。 - Community

0
在我的情况下,解决方案非常简单。我只需要使用context.push('screen')而不是context.go('/screen')

-3

由于这会使操作系统的交互不一致,因此不应在Android上实现此功能。

从屏幕边缘向右滑动以返回并不是Android希望您实现的功能,因此最好不要这样做。


2
尽管我从用户体验的角度同意你的观点,但那并不是对实际问题的回答,而这个问题是合法的。 - Capricorn
@Capricorn 是的,我只是想看看它的实现和感觉如何,但我明白这违反了MD规则。 - Tom O'Sullivan
Android Q 推荐的方式是使用后退手势 https://android-developers.googleblog.com/2019/08/gesture-navigation-backstory.html - Denis Murphy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接