【问题标题】:How to Change Swiping direction of CupertinoPageRoute如何更改 CupertinoPageRoute 的滑动方向
【发布时间】:2021-08-07 19:18:55
【问题描述】:

我正在使用Cupertino Page Route 来产生以下行为

      title: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            //doesn't do what I want to do
            GestureDetector(             
              onTap: () => Navigator.of(context).pushNamed(settingsPage),
              onPanUpdate: (details){
                if(details.delta.dx < 0){
                  Navigator.of(context).pushNamed(settingsPage);
                }
              },
              child: Icon(Icons.settings),
            ),
            //Not my concern for now
            IconButton(
              onPressed: () {},
              icon: const Icon(Icons.notifications, color: Colors.black),
            ),
            //Does what I want it to do
            GestureDetector(
              onTap: () => Navigator.of(context).pushNamed(messages),
              child: Icon(Icons.message),
            ),                    
          ],
        ),

它允许我从从左向右滑动来关闭消息屏幕

很遗憾,它不允许我通过从从右向左滑动来关闭设置屏幕

任何人都知道如何更改CupertinoPageRoute 的滑动方向或使用其他解决方案模仿它的行为?

【问题讨论】:

    标签: flutter dart flutter-animation gesturedetector


    【解决方案1】:

    我认为您无法轻松更改 CupertinoRoute 的滑动方向,但我为您找到了两个简单的解决方案:

    或者 - 为您的具体情况提供更好的解决方案:

    第二个解决方案将最好地重现 CupertinoPageRoute 的行为

    • 此外,它还会为您提供从 HomeScreen 到 Settings/Messages 以及返回 HomeScreen 的动画:

    这就是您如何将上面 GIF 中显示的第二种解决方案 实施到您的应用程序中:

    import 'package:page_transition/page_transition.dart';
    
    class HomeScreen extends StatefulWidget {
      const HomeScreen({Key? key}) : super(key: key);
      @override
      _HomeScreen createState() => _HomeScreen();
    }
    
    class _HomeScreen extends State<HomeScreen> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.white,
          appBar: AppBar(
            backgroundColor: Colors.white,
            automaticallyImplyLeading: false,
            title: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                GestureDetector(
                    onTap: () => Navigator.push(
                          context,
                          //Use Page Transition left to right here
                          PageTransition(
                              // duration: Duration(seconds: 1),
                              type: PageTransitionType.leftToRightWithFade,
                              child: SettingsScreen(),
                              inheritTheme: true,
                              ctx: context),
                        ),
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: const Icon(Icons.settings, color: Colors.black),
                    )),
                IconButton(
                  onPressed: () {},
                  icon: const Icon(Icons.notifications, color: Colors.black),
                ),
                GestureDetector(
                    onTap: () => Navigator.push(
                          context,
                          //Use Page Transition right to left here
                          PageTransition(
                              // duration: Duration(seconds: 1),
                              type: PageTransitionType.rightToLeftWithFade,
                              child: const MessageScreen(),
                              inheritTheme: true,
                              ctx: context),
                        ),
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: const Icon(Icons.message, color: Colors.black),
                    )),
              ],
            ),
          ),
          //body
          body: Container(),
        );
      }
    }
    

    然后在您的设置/消息屏幕中实现一个GestureDetector,它将在Swipe

    上触发

    它会 Navigator.pop(关闭)你的屏幕 - 而 Flutter 会处理反向动画

    class SettingsScreen extends StatefulWidget {
      const SettingsScreen({Key? key}) : super(key: key);
    
      @override
      _SettingsScreen createState() => _SettingsScreen();
    }
    
    class _SettingsScreen extends State<SettingsScreen> {
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
    // This is where you detect swiping from right to left
            onPanUpdate: (details) {
              if (details.delta.dx < -10) {
    // Upon swiping detection it then pops the screen - reverse animation happens without additional code
                Navigator.pop(context);
              }
            },
            child: const Scaffold(
              backgroundColor: Colors.blueGrey,
              body: Center(child: const Text("? Settings")),
            ));
      }
    }
    
    
    // Same code here for your MessageScreen but with opposite swipe gesture detection (left to right)
    
    class MessageScreen extends StatefulWidget {
      const MessageScreen({Key? key}) : super(key: key);
    
      @override
      _MessageScreen createState() => _MessageScreen();
    }
    
    class _MessageScreen extends State<MessageScreen> {
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
            onPanUpdate: (details) {
              if (details.delta.dx > 10) {
                Navigator.pop(context);
              }
            },
            child: const Scaffold(
              backgroundColor: Colors.redAccent,
              body: Center(child: const Text("? Messages")),
            ));
      }
    }
    

    就是这样! - 此方法的唯一缺点是一旦检测到滑动就无法取消它




    ---- 经过与用户的长时间讨论 - 下面的 cmets 已得到解决以上 & 问题已编辑

    【讨论】:

    • 感谢您的回答!但是,如果我删除 onTap 没有任何反应,如果我保留它并使用你给我的代码,它会从右向左滑动而不是从左向右滑动
    • 谢谢,但它仍然从右到左打开也许除了 GestureDetector 之外还有其他东西可以完成这项工作?
    • 你问的是一个完全不同的问题..我已经更新了答案
    • 很抱歉上次没有看到你的更新,所以现在我尝试了你的代码,它可以工作了!非常感谢你的帮助 !它只是不滑动,但至少从左到右打开没有问题,谢谢!
    • 我很难看到你想要向右滑动的内容,也许你云给我一个指向你的 UI 的链接 - 无论如何我很高兴能提供帮助!
    猜你喜欢
    • 2015-12-03
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多