Flutter中命名路由模块化及传参

2020-12-28 14:36:32 浏览数 (2)

Flutter 中的命名路由在实际项目中使用最为常用。

要想使用命名路由首先要配置路由,并引入路由地址对应的页面组件。

代码语言:javascript复制
// main.dart
import 'package:flutter/material.dart';

// 引入子页面
import 'pages/Form.dart';
import 'pages/Search.dart';
import 'pages/Tabs.dart';

// 主函数
void main(){
    runApp(MyApp());
}

class MyApp extends StatelessWidget{
    // 配置路由
    final routes={
        '/form':(context)=>FormPage(),
        '/search':(context,{arguments})=>SearchPage(arguments:arguments)
    };

    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            home: Tabs(),
            onGenerateRoute: (RouteSettings settings) {

                // 官网传参示例

                // 获取当前路由名称
                final String name = settings.name; 
                // 获取路由名称对应的处理方法
                final Function pageContentBuilder = routes[name];
                if (pageContentBuilder != null) {
                    if (settings.arguments != null) {
                        final Route route = MaterialPageRoute(
                            builder: (context) =>
                            pageContentBuilder(context, arguments: settings.arguments)
                        );
                        return route;
                    }else{
                        final Route route = MaterialPageRoute(
                            builder: (context) =>
                            pageContentBuilder(context)
                        );
                        return route;
                    }
                }
            },
            // 主题
            theme: ThemeData(primarySwatch:Colors.yellow)
        );
    }
}

上面的代码中分别引入了三个页面:Form.dart 和 Search.dart 以及 Tabs.dart。

main.dart 主页面引入的子页面 Form.dart 页面代码:

代码语言:javascript复制
// lib/pages/Form.dart
import 'package:flutter/material.dart';

// 表单页面
class FormPage extends StatelessWidget {
    final String title;
    // 无状态组件接受传参
    FormPage({this.title="表单"});

    @override
    Widget build(BuildContext context) {
        return Scaffold(
            // 浮动按钮
            floatingActionButton: FloatingActionButton(
                child: Text('返回'),
                // 点击事件
                onPressed: (){
                    // 返回上一级页面
                    Navigator.of(context).pop();
                },
            ),
            appBar: AppBar(
                title:Text(this.title)
            ),
            body: ListView(
                children: <Widget>[
                    ListTile(
                        title:Text('这是表单页面')
                    )
                ]
            ),
        );
    }
}

main.dart 主页面引入的子页面 Search.dart 页面代码:

代码语言:javascript复制
// lib/pages/Search.dart
import 'package:flutter/material.dart';


// 搜索页面
class SearchPage extends StatefulWidget {
    final Map arguments;
    // 有状态组件接受传参
    SearchPage({Key key,this.arguments}) : super(key: key);
   _SearchPageState createState() => _SearchPageState(arguments:this.arguments);

}

class _SearchPageState extends State<SearchPage> {

    Map arguments;
    _SearchPageState({this.arguments});

    @override
    Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
                title:Text('搜索')
            ),
            body:Container(
                child:Text('搜索商品ID为${arguments["id"]}')
            )
        );
    }
}

main.dart 主页面引入的子页面Tabs.dart 页面代码:

代码语言:javascript复制
// lib/pages/Tabs.dart
import "package:flutter/material.dart";

// 引入子页面
import 'tabs/Home.dart';
import 'tabs/Category.dart';
import 'tabs/Setting.dart';

// 标签切换页
class Tabs extends StatefulWidget {
    Tabs({Key key}) : super(key: key);
    _TabsState createState() => _TabsState();
}

class _TabsState extends State<Tabs>{

    // 当前选中标签的下标
    int _currentIndex = 0;
    // 当前页面数组
    List _pageList = [
        HomePage(),
        CategoryPage(),
        SettingPage()
    ];
    
    @override
    Widget build(BuildContext context) {
    return Container(
        child: Scaffold(
            // 导航条
            appBar:AppBar(title:Text('Flutter App')),
            // 主体
            body:this._pageList[this._currentIndex],
            // 底部导航条
            bottomNavigationBar: BottomNavigationBar(
                // 当前菜单下标
                currentIndex: this._currentIndex,
                // 点击事件,获取当前点击的标签下标
                onTap: (int index){
                    // 改变状态
                    setState(() {
                       this._currentIndex=index;
                    });
                },
                // 图标大小
                iconSize: 30.0,
                // 选中图标的颜色
                fixedColor: Colors.red,
                // 多个标签页的动画效果
                type: BottomNavigationBarType.fixed,
                items: [
                    // 只能是BottomNavigationBarItem的类型
                    BottomNavigationBarItem(
                        icon:Icon(Icons.home),
                        label:"首页"
                    ),
                    BottomNavigationBarItem(
                        icon:Icon(Icons.category),
                        label:"分类"
                    ),
                    BottomNavigationBarItem(
                        icon:Icon(Icons.settings),
                        label:"设置"
                    )
                ]
            ),
        ));
    }
}

上面 Tabs 页面代码中引入了三个子页面,分别是 Home.dart 和 Category.dart 以及 Setting.dart。

Tabs 页面的子页面 Home.dart 页面代码:

代码语言:javascript复制
// lib/pages/tabs/Home.dart
import 'package:flutter/material.dart';

// 主页页面
class HomePage extends StatefulWidget {
    HomePage({Key key}) : super(key: key);
    _HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
    @override
    Widget build(BuildContext context) {
        return Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
                RaisedButton(
                    child: Text("跳转到搜索页面"),
                    // 点击事件
                    onPressed: () {
                        // 跳转路由传值
                        Navigator.pushNamed(context, '/search',arguments: {
                            "id":123
                        });
                    },
                    color: Theme.of(context).accentColor,
                    textTheme: ButtonTextTheme.primary
                )
            ],
        );
    }
}

Tabs 页面的子页面Category.dart页面代码:

代码语言:javascript复制
// lib/pages/tabs/Gategory.dart
import "package:flutter/material.dart";

// 分类页面
class CategoryPage extends StatefulWidget {
    CategoryPage({Key key}) : super(key: key);
    _CategoryPageState createState() => _CategoryPageState();
}

class _CategoryPageState extends State<CategoryPage> {
    @override
    Widget build(BuildContext context) {
        return Column(
            // 主轴对齐式式
            mainAxisAlignment:MainAxisAlignment.center,
            // 交叉轴对齐方式
            crossAxisAlignment: CrossAxisAlignment.center,
            children:<Widget>[
                RaisedButton(
                    child: Text("跳转到表单页面"),
                    // 点击事件
                    onPressed: () {
                        Navigator.pushNamed(context, '/form');
                    },
                    color: Theme.of(context).accentColor,
                    textTheme: ButtonTextTheme.primary
                )
            ]
        );
    }
}

Tabs 页面的子页面Setting.dart 页面代码:

代码语言:javascript复制
// lib/pages/tabs/Setting.dart
import "package:flutter/material.dart";

// 设置页面
class SettingPage extends StatefulWidget {
    SettingPage({Key key}) : super(key: key);
    _SettingPageState createState() => _SettingPageState();
}

class _SettingPageState extends State<SettingPage> {
    @override
    Widget build(BuildContext context) {
        return Container(
            child: Text("这是设置页面")
        );
    }
}

从上面的代码可以看出,配置路由后,就可以用 Navigator.pushNamed(context,routeName) 方法来进行路由跳转了。

对于页面较少的情况下,我们可以在主页面中直接引入所有路由对应的子页面,当页面较多时,需要将路由进行模块化。

首先定义一个单独的路由文件,并引入路由对应的组件,添加路由监听事件。

代码语言:javascript复制
// lib/routes/Routes.dart

import 'package:flutter/material.dart';

import '../pages/Tabs.dart';
import '../pages/Form.dart';
import '../pages/Search.dart';


final routes={
    '/':(context)=>Tabs(),
    '/form':(context)=>FormPage(),
    '/search':(context,{arguments})=>SearchPage(arguments:arguments),
};


Function onGenerateRoute=(RouteSettings settings) {
    // 官网传参示例
    // 获取当前路由名称
    final String name = settings.name; 
    // 获取路由名称对应的处理方法
    final Function pageContentBuilder = routes[name];
    if (pageContentBuilder != null) {
        if (settings.arguments != null) {
            final Route route = MaterialPageRoute(
                builder: (context) =>
                pageContentBuilder(context, arguments: settings.arguments)
            );
            return route;
        }else{
            final Route route = MaterialPageRoute(
                builder: (context) =>
                pageContentBuilder(context)
            );
            return route;
        }
    }
};

然后在main.dart中引入单独抽离的路由文件。

代码语言:javascript复制
// main.dart
import 'package:flutter/material.dart';

// 引入路由管理
import 'routes/Routes.dart';

// 主函数
void main(){
    runApp(MyApp());
}


class MyApp extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            // 初始化的路由
            initialRoute: '/',
            // 监听路由事件
            onGenerateRoute:onGenerateRoute,
            // 主题
            theme: ThemeData(primarySwatch:Colors.yellow)
        );
    }
}

0 人点赞