导航到 Flutter 中的新屏幕

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

如何在 Flutter 中导航到新屏幕?

这些问题很相似,但比我问的更多。

我在下面添加答案。

dart navigation flutter
14个回答
72
投票

导航到新屏幕:

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: const Text('Home Screen')),
      body: Center(
        child: ElevatedButton(
          child: const 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: const Text('New Screen')),
      body: const Center(
        child: Text(
          'This is a new screen',
          style: TextStyle(fontSize: 24.0),
        ),
      ),
    );
  }
}

另请参阅


23
投票

要加载带有 Flutter 预制动画的新屏幕,请使用它们各自的转换类。例如:

容器转型

基本上,我们将第一个小部件或屏幕转换为下一个屏幕。为此,我们需要使用

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 中的转换。我们需要

SharedAxisTransition
PageTransitionSwitcher
,以及一个状态来模拟活动页面和上一页之间的转换。如果我们只在两个页面之间切换,我们可以使用一个简单的布尔值
isFirstPage
。这是使用 Provider 作为状态管理的代码片段:

  @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,因此您可能需要先检查一下。


14
投票

使用

Navigator.push()

返回下一个屏幕
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),);

使用

Navigator.pushReplacement()

导航到下一个屏幕而不返回
Navigator.pushReplacement(
context,MaterialPageRoute(builder: (context) => SecondRoute()),);

5
投票
onTap: () {
  Navigator.push(context,
      MaterialPageRoute(builder: (context) => NextScreenName()));
}

5
投票

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

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

4
投票

如果您熟悉 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(),
      },
    );
  }
}

您可以从

onPressed
添加按钮
homepage.dart
事件来导航
register.dart
,如下所示。

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

4
投票

In formal method :

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

在 GetX 方法中:

Get.to(Second());

如果我们可以将屏幕导航到另一个页面并从堆栈中删除当前页面,那么我们可以使用下面定义的方法:

Get.off(Third());

如果我们可以将屏幕导航到另一个页面并从堆栈中删除所有路由或页面,那么我们可以使用下面定义的方法:

Get.offAll(Third());

如果我们想使用 Navigator.pop() 那么 GetX 给出一个定义如下的方法:

Get.back();

3
投票
FloatingActionButton(
  onPressed: (){
    Navigator.of(context).push(MaterialPageRoute(builder: (context) => const AddUser()));
  },
  child: const Icon(Icons.add),
),

2
投票

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

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


1
投票

您可以尝试使用以下代码

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

1
投票

我发现了一个很好的教程,我一直在遵循,它非常全面,有屏幕截图和一步一步,您也可以下载代码并运行它。对我学习 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


0
投票

使用Get插件,您只需调用

即可导航到新页面
Get.to(Page());

0
投票

这样您就可以呈现下一个屏幕

Navigator.of(context).push(
   MaterialPageRoute(fullscreenDialog: true,
   builder: (context) => const NewScreen(),
   ),
);

0
投票
flutter_quick_router: ^0.0.2

QuickRouter 提供了使用 Flutter 中的 Navigator 小部件在路由之间导航的便捷方法。它支持常规和可恢复路线,并提供各种过渡类型。

导航到其他屏幕

context.to(const SecondScreen());

返回旧屏幕

context.back();
© www.soinside.com 2019 - 2024. All rights reserved.