美文网首页
Flutter之Router和Navigator实现页面跳转

Flutter之Router和Navigator实现页面跳转

作者: 有没有口罩给我一个 | 来源:发表于2019-05-26 13:18 被阅读0次

大多数应用程序都具有多个Page或View,并且希望将用户从当前Page平滑过渡到另一个页面。Flutter的路由和导航功能可帮助您管理应用中屏幕之间的命名和过渡。

概述

管理多个页面时有两个核心概念和类:Route和 Navigator。 一个route是一个屏幕或页面的抽象,Navigator是管理route的Widget。Navigator可以通过route入栈和出栈来实现页面之间的跳转。

  • 从First页面导航到second页面并返回FIrst页面:

      void main() => runApp(new MaterialApp(
      title: 'Navigation Basics',
      home: FirstRoute(),
      ));
    
      class FirstRoute extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
      return Scaffold(
      appBar: AppBar(
      title: Text('First Route'),
      ),
      body: Center(
      child: RaisedButton(
        child: Text('Open route'),
        onPressed: () {
          // Navigate to second route when tapped.
          Navigator.of(context).push(new MaterialPageRoute(
              builder: (BuildContext context) => SecondRoute()));
        },
      ),
      ),
      );
      }
      }
    
      class SecondRoute extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
      return Scaffold(
      appBar: AppBar(
      title: Text("Second Route"),
      ),
       body: Center(
      child: RaisedButton(
        onPressed: () {
          // Navigate back to first route when tapped.
          Navigator.pop(context);
        },
        child: Text('Go back!'),
      ),
      ),
      );
      }
      }
    
  • 从A页面发送数据去B的页面,实际上是通过构造函数传递数据:

    class Todo {
        final String title;
        final String describe;

        Todo(this.title, this.describe);
    }

    class TodosScreen extends StatelessWidget {
            final List<Todo> todos;

            const TodosScreen({Key key, this.todos}) : super(key: key);

        @override
        Widget build(BuildContext context) {
        return new Scaffold(
            appBar: new AppBar(
            title: new Text('Todos'),
        ),
        body: new ListView.builder(
            itemCount: todos.length,
      itemBuilder: (BuildContext context, int index) {
        return new ListTile(
          title: new Text('todos[index].title'),
          onTap: () {
            Navigator.push(
                context,
                new MaterialPageRoute(
                    builder: (BuildContext context) => new DetailScreen(
                          todo: todos[index],
                        )));
          },
        );
      }),
    );
    }
    }

    class DetailScreen extends StatelessWidget {
            final Todo todo;

            const DetailScreen({Key key, this.todo}) : super(key: key);

    @override
    Widget build(BuildContext context) {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text('${todo.title}'),
        ),
        body: new Padding(
        padding: EdgeInsets.all(16.0),
    child: new Text(todo.describe),
      ),
     );
    }
    }
  • 等待其他页面返回数据
    class HomeScreen extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
    title: Text('Returning Data Demo'),
    ),
    body: Center(child: SelectionButton()),
    );
    }
    }

    class SelectionButton extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return RaisedButton(
    onPressed: () {
    _navigateAndDisplaySelection(context);
     },
    child: Text('Pick an option, any option!'),
    );
    }

    ///运行SelectionScreen页面并且等待SelectionScreen Navigator.pop!返回结果
    void _navigateAndDisplaySelection(BuildContext context) async {
    ///Navigator.push 将在我们调用SelectionScreen页面的Navigator.pop完成后返回一个携带结果数据Future
    final result =
    await Navigator.push(context, new MaterialPageRoute(builder: (context) {
     return SelectionScreen();
    }));

    //    String valResult = await result;

    ///之后等待SelectionScreen页面返回结果,隐藏任意上一个的SnackBars,并显示并将结果显示在SnackBar
    Scaffold.of(context)
        ..removeCurrentSnackBar()
        ..showSnackBar(new SnackBar(content: new Text(result)));
             }
            }

    class SelectionScreen extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return new Scaffold(
    appBar: AppBar(
    title: Text('Pick an option'),
    ),
    body: Center(
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: RaisedButton(
            onPressed: () {
              // Close the screen and return "Yep!" as the result
              Navigator.pop(context, 'Yep!');
            },
            child: Text('Yep!'),
          ),
        ),
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: RaisedButton(
            onPressed: () {
              // Close the screen and return "Nope!" as the result
              Navigator.pop(context, 'Nope.');
            },
            child: Text('Nope.'),
          ),
        )
      ],
    ),
        ),
        );
    }
    }
  • 通过名字路由到其他页面
    void main() {
    runApp(MaterialApp(
    title: 'Named Routes Demo',
     // Start the app with the "/" named route. In our case, the app will start
     // on the FirstScreen Widget
     initialRoute: '/',
        routes: {
        // When we navigate to the "/" route, build the FirstScreen Widget
        '/': (context) => FirstScreen(),
        // When we navigate to the "/second" route, build the SecondScreen Widget
         '/second': (context) => SecondScreen(),
     },
    ));
    }

    class FirstScreen extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
    title: Text('First Screen'),
        ),
        body: Center(
    child: RaisedButton(
      child: Text('Launch screen'),
      onPressed: () {
        // Navigate to the second screen using a named route
        Navigator.pushNamed(context, '/second');
      },
    ),
         ),
        );
    }
    }

    class SecondScreen extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
    title: Text("Second Screen"),
        ),
        body: Center(
    child: RaisedButton(
      onPressed: () {
        // Navigate back to the first screen by popping the current route
        // off the stack
        Navigator.pop(context);
      },
      child: Text('Go back!'),
    ),
        ),
     );
    }
    }
  • 跳转页面添加过度动画
    class HeroApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    title: 'Transition Demo',
    home: MainScreen(),
    );
    }
    }

    class MainScreen extends StatelessWidget {

    @override
    Widget build(BuildContext context) {
        return Scaffold(
    appBar: AppBar(
    title: Text('Main Screen'),
    ),
    body: GestureDetector(
    child: Hero(
      tag: 'imageHero',
      child: Image.network(
        'http://pic37.nipic.com/20140113/8800276_184927469000_2.png',
      ),
    ),

    ///transitionsBuilder
    ///I/flutter (21575): pageBuilder
    ///I/flutter (21575): transitionsBuilder
    ///I/flutter (21575): transitionsBuilder
    ///I/flutter (21575): transitionsBuilder
    onTap: () {
      Navigator.push(
          context,
          new PageRouteBuilder(
              transitionDuration: new Duration(seconds: 2),
              transitionsBuilder: (BuildContext context,
                  Animation<double> animation,
                  Animation<double> secondaryAnimation,
                  Widget child) {
                print('transitionsBuilder  这里会一直执行到动画结束');
    //                    return SlideTransition(
    //                      position: new Tween<Offset>(
    //                        begin: const Offset(0.0, 1.0),
    //                        end: Offset.zero,
    //                      ).animate(animation),
    //                      child: SlideTransition(
    //                        position: Tween<Offset>(
    //                          begin: Offset.zero,
    //                          end: const Offset(0.0, 1.0),
    //                        ).animate(secondaryAnimation),
    //                        child: child,
    //                      ),
    //                    );

                return SlideTransition(
                  position: Tween<Offset>(
                    begin: const Offset(0.0, 1.0),
                    end: Offset.zero,
                  ).animate(animation),
                  child: child, // child is the value returned by pageBuilder
                );
              },
              pageBuilder: (BuildContext context,
                  Animation<double> animation,
                  Animation<double> secondaryAnimation) {
                print('pageBuilder');
                return new DetailScreen();
              }));
    },
    ),
    );
    }
    }

    class DetailScreen extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return Scaffold(
     body: GestureDetector(
    child: Center(
      child: Hero(
        tag: 'imageHero',
        child: Image.network(
          'http://pic37.nipic.com/20140113/8800276_184927469000_2.png',
        ),
      ),
    ),
    onTap: () {
      Navigator.pop(context);
    },
     ),
     );
    }
    }
  • 自定义Router

    class CustomRoute extends PageRouteBuilder {
      final Widget widget;
    
    CustomRoute(this.widget)
    : super(
          // 设置过度时间
          transitionDuration: Duration(seconds: 1),
          // 构造器
          pageBuilder: (
            // 上下文和动画
            BuildContext context,
            Animation<double> animaton1,
            Animation<double> animaton2,
          ) {
            return widget;
          },
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animaton1,
            Animation<double> animaton2,
            Widget child,
          ) {
    //              旋转加缩放动画效果
            return RotationTransition(
              turns: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
                parent: animaton1,
                curve: Curves.fastOutSlowIn,
              )),
              child: ScaleTransition(
                scale: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
                    parent: animaton1, curve: Curves.fastOutSlowIn)),
                child: child,
              ),
            );
          });
    }
    

使用很简单:

   final result =
    await Navigator.push(context, new CustomRoute(SelectionScreen()));

//    String valResult = await result;

///之后等待SelectionScreen页面返回结果,隐藏任意上一个的SnackBars,并显示并将结果显示在SnackBar
Scaffold.of(context)
  ..removeCurrentSnackBar()
  ..showSnackBar(new SnackBar(content: new Text(result)));

最后附上demo链接

相关文章

  • Flutter - 页面跳转(路由)、传值

    Flutter 中页面跳转通过 Navigator 和 Route 来实现。 一、页面跳转 1,常规路由页面跳转...

  • Flutter之Router和Navigator实现页面跳转

    大多数应用程序都具有多个Page或View,并且希望将用户从当前Page平滑过渡到另一个页面。Flutter的路由...

  • flutter 路由

    Navigator 参数 push 将设置的router信息推送到Navigator上,实现页面跳转。 of 主要...

  • Flutter router

    在Flutter开发的页面间实现跳转的话,一切都离不开Navigator,系统提供了Navigator管理界面跳转...

  • Flutter细节记录

    一、路由 flutter进行页面跳转是由路由来实现的(Route),Navigator负责Route的压入和弹出。...

  • 2019-11-11 Flutter 页面如何跳转?

    Flutter 页面如何跳转? 一、Navigator介绍 Navigator 继承自 StatefulWidge...

  • Navigator的正确打开方式

    引言 在使用Flutter进行页面间跳转时,Flutter官方给的建议是使用Navigator。Navigator...

  • Flutter 之Router 页面跳转

    Flutter 之Router 页面跳转 页面跳转在移动开发中是很常见的事情,在Android中打开另外一个页面主...

  • Flutter 之 导航

    在 Flutter 中,页面之间的跳转是通过 Route 和 Navigator 来管理的: Route 是页面的...

  • Flutter Navigation(导航)

    在 Flutter 里实现页面的导航需要使用两个类:Navigator和 Route。Navigator 负责页面...

网友评论

      本文标题:Flutter之Router和Navigator实现页面跳转

      本文链接:https://www.haomeiwen.com/subject/bayxtctx.html