【问题标题】:Navigate to a new screen in Flutter在 Flutter 中导航到新屏幕
【发布时间】:2019-06-07 11:58:28
【问题描述】:

【问题讨论】:

  • 我不确定我对此有何感想。我认为问题的低级是有限度的。我的意思是如果这个问题/答案很好,那么我们可以为框架中的任何小部件做一个
  • 当然,但是您的问题属于“太宽泛”的 IMO。
  • 我认为问题的低级必须有一个限制。正如@RémiRousselet 所说,我们可以为框架中的任何小部件做到这一点,而且这个问题的文档非常明显。
  • flutter 文档在这个主题上非常简单。 flutter.dev/docs/cookbook/navigation/navigation-basics

标签: dart navigation flutter


【解决方案1】:

导航到新屏幕:

Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewScreen()));

其中context 是小部件的BuildContext,NewScreen 是第二个小部件布局的名称。

代码

main.dart

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home Screen')),
      body: Center(
        child: RaisedButton(
          child: Text(
            'Navigate to a new screen >>',
            style: TextStyle(fontSize: 24.0),
          ),
          onPressed: () {
            _navigateToNextScreen(context);
          },
        ),
      ),
    );
  }

  void _navigateToNextScreen(BuildContext context) {
    Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewScreen()));
  }
}

class NewScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('New Screen')),
      body: Center(
        child: Text(
          'This is a new screen',
          style: TextStyle(fontSize: 24.0),
        ),
      ),
    );
  }
}

另见

【讨论】:

  • 这是什么原因?你每隔一天就这样做一次……为什么?也许你应该写一个博客之类的?
  • @westdabestdb 他每周做 3-4 次,我不知道这样做的目的是什么......
  • @westdabestdb "and we all know Flutter has well-written documentation." - 好吧,我会反对... ;-(
  • @pskink 没错,阅读源代码比花时间阅读文档要好 10 倍,所以两者兼而有之是解决之道。
  • 我回答关于 SO 的问题,因为它可以帮助我更好地学习。几乎我回答的每一个问题都是我自己的问题。当我有问题时,我会谷歌它。如果我在 SO 上找不到快速答案或副本,那么我会写一个问答对。
【解决方案2】:

要使用 Flutter 预装 animations 加载新屏幕,请使用它们各自的转换类。例如:

容器转换

基本上,我们将第一个小部件或屏幕转换为下一个屏幕。为此,我们需要使用OpenContainer。下面的代码说明了 ListView 中的一个项目转换为它的详细信息页面。

  @override
  Widget build(BuildContext context) {
    return Card(
      color: Colors.white,
      elevation: 2.0,
      child: OpenContainer(
        transitionType: ContainerTransitionType.fadeThrough,
        closedColor: Theme.of(context).cardColor,
        closedElevation: 0.0,
        openElevation: 4.0,
        transitionDuration: Duration(milliseconds: 1500),
        openBuilder: (BuildContext context, VoidCallback _) => THENEXTSCREEN(),
        closedBuilder: (BuildContext _, VoidCallback openContainer) {
          return ListTile(
            leading: Icon(Icons.album),
            title: Text("ITEM NAME"),
          );
        },
      ),
    );
  }

共享轴

此过渡类似于 Tab 或 Stepper 中的过渡。我们需要SharedAxisTransitionPageTransitionSwitcher,以及用于模拟活动页面和前一页面之间转换的状态。如果我们只在两个页面之间切换,我们可以使用一个简单的布尔值isFirstPage。这是使用 Provider 作为状态管理的 sn-p:

  @override
  Widget build(BuildContext context) {
    return Consumer<YourState>(
      builder: (context, state, child) {
        return PageTransitionSwitcher(
          duration: const Duration(milliseconds: 1500),
          reverse: !state.isFirstPage, // STATE
          transitionBuilder: (
            Widget child,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) {
            return SharedAxisTransition(
              child: child,
              animation: animation,
              secondaryAnimation: secondaryAnimation,
              transitionType: SharedAxisTransitionType.horizontal,
            );
          },
          child: state.isFirstPage? FIRSTPAGE() : SECONDPAGE(), // STATE
        );
      },
    );
  }

请注意,在所有这些场景中,我们都不使用 Navigator 和 MaterialPageRoute。所有这些代码均来自animations repo,因此您可能需要先查看一下。

【讨论】:

    【解决方案3】:

    使用Navigator.push()返回下一个屏幕

    Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => SecondRoute()),);
    

    使用Navigator.pushReplacement()直接导航到下一个屏幕

    Navigator.pushReplacement(
    context,MaterialPageRoute(builder: (context) => SecondRoute()),);
    

    【讨论】:

      【解决方案4】:
      onTap: () {
        Navigator.push(context,
            MaterialPageRoute(builder: (context) => NextScreenName()));
      }
      

      【讨论】:

      • 虽然您的答案可能是正确的(我不知道是否正确),但如果您解释它的作用和原因,它对未来的搜索者会更有价值
      • 嗨@MindSwipe,请参考这个问题。所以基本上,它用于从一个屏幕导航到另一个屏幕
      【解决方案5】:

      如果您熟悉 Web 开发,此方法类似于路由。

      main.dart

      void main() {
        setupLocator();
        runApp(MyApp());
      }
      
      class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            title: 'Flutter Demo',
            routes: {
              '/' : (BuildContext context)=>HomePage(),
              '/register' : (BuildContext context)=>RegisterPage(),
            },
          );
        }
      }
      

      您可以从homepage.dart 添加按钮onPressed 事件以导航register.dart,如下所示。

      onPressed: (){
          Navigator.pushReplacementNamed(context, '/register');
       },
      

      【讨论】:

        【解决方案6】:

        这是一个完整的路由推送/弹出示例:

        import 'package:flutter/material.dart';
        
        void main() {
          runApp(MyApp());
        }
        
        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              title: 'Flutter Routes',
              routes: {
                '/login': (BuildContext context) => Login(),
                // add another route here
                // '/register': (BuildContext context) => Register(),
              },
              theme: ThemeData(
                primarySwatch: Colors.blue,
                visualDensity: VisualDensity.adaptivePlatformDensity,
              ),
              home: MyHomePage(title: 'Flutter Routes'),
            );
          }
        }
        
        class MyHomePage extends StatefulWidget {
          MyHomePage({Key key, this.title}) : super(key: key);
        
          final String title;
        
          @override
          _MyHomePageState createState() => _MyHomePageState();
        }
        
        class _MyHomePageState extends State<MyHomePage> {
          @override
          Widget build(BuildContext context) {
            return Scaffold(
              appBar: AppBar(
                title: Text(widget.title),
              ),
              body: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    RaisedButton(
                      onPressed: () {
                        // This gives the back button:
                        Navigator.of(context).pushNamed('/login');
        
                        // This doesn't give the back button (it replaces)
                        //Navigator.pushReplacementNamed(context, '/login');
                      },
                      child: Text('Login'),
                    ),
                  ],
                ),
              ),
            );
          }
        }
        
        class Login extends StatefulWidget {
          @override
          _LoginState createState() => _LoginState();
        }
        
        class _LoginState extends State<Login> {
          @override
          Widget build(BuildContext context) {
            return Scaffold(
                appBar: AppBar(
                  title: Text('Login Page'),
                ),
                body: Center(
                  child: RaisedButton(
                    onPressed: () {
                      // This will only work for pushNamed
                      Navigator.of(context).pop();
                    },
                    child: Text('Go back'),
                  ),
                ));
          }
        }
        

        【讨论】:

          【解决方案7】:

          你可以试试下面的代码

          Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => YourNextScreen())),
          

          【讨论】:

            【解决方案8】:

            我找到了一个很好的教程,我一直在学习,它非常全面,有截图和一步一步,你也可以下载代码并运行它。对我学习 Flutter 很有帮助,尤其是我完全是初学者。

            https://medium.com/@misterflutter/lesson-5-creating-new-screens-f740994190c7

            https://medium.com/@misterflutter/lesson-6-creating-new-screens-part-2-4997085a43af?sk=d2a0fb723af42b78800f7cf19b312b62

            【讨论】:

              【解决方案9】:

              Flutter 也有类似的实现,使用 NavigatorRoutes。 Route 是应用程序“屏幕”或“页面”的抽象,而 Navigator 是管理路由的小部件。

              要在页面之间导航,您有几个选项:

              • 指定路线名称映射。
              • 直接导航到路线。

              以下示例构建一个地图。

              void main() {
                runApp(CupertinoApp(
                  home: MyAppHome(), // becomes the route named '/'
                  routes: <String, WidgetBuilder> {
                    '/a': (BuildContext context) => MyPage(title: 'page A'),
                    '/b': (BuildContext context) => MyPage(title: 'page B'),
                    '/c': (BuildContext context) => MyPage(title: 'page C'),
                  },
                ));
              }
              

              通过pushing 导航到route 其名称到导航器。

              Navigator.of(context).pushNamed('/b');
              

              Navigator 类处理 Flutter 中的路由,并用于从您压入堆栈的路由中获取结果。这是由awaitingFuture 返回的push() 完成的。

              例如,要启动让用户选择其位置的“位置”路线,您可以执行以下操作:

              Map coordinates = await Navigator.of(context).pushNamed('/location');
              

              然后,在您的“位置”路线中,一旦用户选择了他们的位置,pop() 就会显示结果堆栈:

              Navigator.of(context).pop({"lat":43.821757,"long":-79.226392});
              

              【讨论】:

                【解决方案10】:

                您可以在构建小部件中使用这种方式

                onTap: () { Navigator.of(context).push(MaterialPageRoute( builder: (context) =&gt; NewScreen()));},

                【讨论】:

                  【解决方案11】:

                  使用Get plugin,您只需调用即可导航到新页面

                  Get.to(Page());
                  

                  【讨论】:

                    猜你喜欢
                    • 2019-12-02
                    • 2020-03-06
                    • 1970-01-01
                    • 2019-03-12
                    • 1970-01-01
                    • 1970-01-01
                    • 2020-11-13
                    • 2020-06-03
                    • 1970-01-01
                    相关资源
                    最近更新 更多