Flutter中的路由实现方式

导航到一个新页面和返回

Navigator.push方法
跳转后样子
自带返回

import 'package:flutter/material.dart';

void main(){
  runApp(MaterialApp(
    title: '基本路由',
    home: FirstRoute(),
  ));
}

class FirstRoute extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('First Route'),
      ),
      body: Center(
        child: RaisedButton(
            child: Text('Open route'),
            onPressed: (){
//              Navigator.push跳转的页面自带返回键
              Navigator.push(context, MaterialPageRoute(builder: (context) => SecondRoute()));
            }
        ),
      ),
    );
  }
}

class SecondRoute extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Route'),
      ),
      body: Center(
        child: RaisedButton(
            child: Text('Go back'),
            onPressed: (){
              Navigator.pop(context);
            }),
      ),
    );
  }
}


导航到一个新页面带参数返回

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: '带参数返回路由',
    home: HomeScreen(),
  ));
}
//第一屏页面
class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Returning with data'),
      ),
      body: Center(
        child: SelectionButton(),
      ),
    );
  }
}

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

  _navigateAndDisplaySelection(BuildContext context) async {
    //用result接受第二屏的返回值
    final result = await Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => SelectionScreen()),
    );
    //级联操作符 (..) 可以在同一个对象上 连续调用多个函数以及访问成员变量。 使用级联操作符可以避免创建 临时变量
    Scaffold.of(context)
    ..removeCurrentSnackBar()
    ..showSnackBar(SnackBar(content: Text("$result"),));
  }
}

//第二屏页面
class SelectionScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return 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: () {
                  // 在这里返回 "Yep"
                  Navigator.pop(context,'Yep!');
                },
                child: Text('Yep'),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: RaisedButton(
                onPressed: () {
                  // 在这里返回 "Noep"
                  Navigator.pop(context,'Noep!');
                }, child: Text('Noep'),),
            ),
          ],
        ),
      ),
    );
  }
}

通过构造函数携带参数跳转

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';

void main() {
  runApp(MaterialApp(
    title: '携参数跳转',
    home:TodosScreen(todos: List.generate(20, (i)=> Todo(
      'Todo $i',
      'A description of what needs to be done for Todo $i'
    ))),
  ));
}

// 数据类(要携带的数据)
class Todo {
  final String title;
  final String description;

  Todo(this.title, this.description);

}

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

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

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

}

//构造函数接受传递过来的参数
class DetailScreen extends StatelessWidget{
  final Todo todo;

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

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text(todo.title),
      ),
      body: Padding(padding: EdgeInsets.all(16.0),child: Text(todo.description),),
    );
  }
}

通过RoutSettings携带参数跳转

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';

void main() {
  runApp(MaterialApp(
    title: 'RouteSettings携参数跳转',
    home: TodosScreen(
        todos: List.generate(
            20,
            (i) => Todo('Todo $i',
                'A description of what needs to be done for Todo $i'))),
  ));
}

// 数据类(要携带的数据)
class Todo {
  final String title;
  final String description;

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

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

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

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Todos'),
      ),
      body: ListView.builder(
          itemCount: todos.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(todos[index].title),
              onTap: () {
                Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => DetailScreen(),
                      //通过RouteSettings传递参数
                      settings: RouteSettings(
                        arguments: todos[index]
                      )
                    ));
              },
            );
          }),
    );
  }
}

//构造函数接受传递过来的参数
class DetailScreen extends StatelessWidget {

//  DetailScreen({Key key, @required this.todo}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    //通过ModalRoute取参数
    final Todo todo = ModalRoute.of(context).settings.arguments;

    return Scaffold(
      appBar: AppBar(
        title: Text(todo.title),
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Text(todo.description),
      ),
    );
  }
}

命名路由

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: '命名路由',
    //当使用 initialRoute 时,需要确保你没有同时定义 home 属性
    initialRoute: '/',
    routes: {
      // 当我们跳转到“/”时,构建 FirstScreen
      '/':(context) => FirstScreen(),
      // 当我们跳转到“/second”时,构建 SecondScreen
      '/second':(context) =>SecondScreen(),
    },
  ));
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('First Screen'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
//          点击时跳转到第二个界面
            Navigator.pushNamed(context, '/second');
          },
          child: Text('Launch screen'),),
      ),
    );
  }

}
class SecondScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Screen'),
      ),
      body: Center(
        child: RaisedButton(onPressed: (){
          // 点击时跳转回第一个界面!
          Navigator.pop(context);
        },child: Text('Go back!'),),
      ),
    );
  }
  
}

给特定路由传参

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      //通过 onGenerateRoute() 函数提取参数,然后把参数传递给组件,和routes是两种方式
      onGenerateRoute: (settings) {
        if (settings.name == PassArgumentsScreen.routeName) {
          final ScreenArguments arguments = settings.arguments;

          return MaterialPageRoute(builder: (context) {
            return PassArgumentsScreen(
              title: arguments.title,
              message: arguments.message,
            );
          });
        }
        return null;
      },
      title: '给特定路由传参',
      home: HomeScreen(),
      routes: {
        //把组件注册到路由表中
        ExtractArgumentsScreen.routeName: (context) => ExtractArgumentsScreen(),
      },
    );
  }
}

class ScreenArguments {
  final String title;
  final String message;

  ScreenArguments(this.title, this.message);
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Screen'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
              onPressed: () {
                Navigator.pushNamed(context, ExtractArgumentsScreen.routeName,
                    arguments: ScreenArguments(
                      '秦时明月',
                      '沧海横流',
                    ));
              },
              child: Text('Navigate to screen that extracts arguments'),
            ),
            RaisedButton(
              onPressed: () {
                Navigator.pushNamed(context, PassArgumentsScreen.routeName,
                    arguments: ScreenArguments(
                        '九歌·少司命',
                        '悲莫悲兮生别离,乐莫乐兮新相知'
                    )
                );
              },
              child: Text('Navigate to a named that accepts arguments'),
            ),
          ],
        ),
      ),
    );
  }
}

//ModalRoute接受参数
class ExtractArgumentsScreen extends StatelessWidget {
  static const routeName = '/extractArguments';

  @override
  Widget build(BuildContext context) {
//    ModalRoute.of() 方法返回的是当前路由及其携带的参数
    final ScreenArguments arguments = ModalRoute.of(context).settings.arguments;
    return Scaffold(
      appBar: AppBar(
        title: Text(arguments.title),
      ),
      body: Center(
        child: Text(arguments.message),
      ),
    );
  }
}

//构造方法接受参数
class PassArgumentsScreen extends StatelessWidget {
  static const routeName = '/passArguments';

  final String title;
  final String message;

  PassArgumentsScreen({Key key, @required this.title, @required this.message})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child: Text(message),
      ),
    );
  }
}

转场动画路由Hero

import 'package:flutter/material.dart';

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

class HeroAPP extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: 'Transition Demo',
      home: MainScreen(),
    );
  }

}
class MainScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Main Screen'),
      ),
      body: GestureDetector(
          onTap: () {
            Navigator.push(context, MaterialPageRoute(builder: (_) {
              return DetailScreen();
            }));
          },
          child: Hero(
            tag: 'imageHero',
            child: Image.network('https://picsum.photos/250?image=9'),
          )),
    );
  }
}

class DetailScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      body: GestureDetector(
        onTap: () {
          Navigator.pop(context);
        },
        child: Center(
          child: Hero(
            tag: 'imageHero',
            child: Image.network('https://picsum.photos/250?image=9'),
          ),
        ),
      ),
    );
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值