26、Flutter中命名路由

发布时间 2023-12-25 14:59:32作者: 鲤斌

Flutter 中的命名路由

main.dart中配置路由

void main() {
  runApp(MaterialApp(
    theme: ThemeData(
      appBarTheme: const AppBarTheme(
        color: Colors.blue, // 设置导航栏颜色 (新版本的设置方法)
      ),
    ),
    // home: Scaffold(body: MyFlutter1())
    initialRoute: "/", //初始化路由
    routes: {
      "/": (contxt) => const MyFlutter1(),
      "/form": (contxt) => const FormPage(),
      // "/news": (contxt)=>const SearchMyApp(),
      "/news": (contxt) {
        return const SearchMyApp();
      }, //类似
    },
  ));
}

跳转路由

class TimePag extends StatefulWidget {
  const TimePag({super.key});

  @override
  State<TimePag> createState() => _TimePagState();
}
class _TimePagState extends State<TimePag> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
            onPressed: () {
              Navigator.pushNamed(context, "/news"); //命名路由跳转
            },
            child: const Text("命名路由跳转"))
      ],
    );
  }
}

Flutter 中的命名路由传值

配置onGenerateRoute

class MyApp1 extends StatelessWidget {
  //1.配置路由
  Map routes = {
    "/": (contxt) => const MyFlutter1(),
    "/form": (contxt) => const FormPage(),
    // "/news": (contxt)=>const SearchMyApp(),
    "/news": (contxt, {arguments}) {
      return SearchMyApp(arguments: arguments); //命名路由传参
    }, //类似
  };
  MyApp1({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        appBarTheme: const AppBarTheme(
          color: Colors.blue, // 设置导航栏颜色 (新版本的设置方法)
        ),
      ),
      // home: Scaffold(body: MyFlutter1())
      initialRoute: "/", //初始化路由
      //2、调用onGenerateRoute处理(固定写法)
      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;
          }
        }
        return null;
      },
    );
  }
}

定义页面接收arguments传参

//其他页面跳转到本页面进行传参
class SearchMyApp extends StatefulWidget {

  final Map arguments;

 const  SearchMyApp({super.key,required this.arguments});  //必须传入

  @override
  State<SearchMyApp> createState() => _SearchMyAppState();
}

class _SearchMyAppState extends State<SearchMyApp> {

  @override
  void initState() {
    super.initState();
    print(widget.arguments);  //参数
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("新闻页面"),
      ),
      body: Center(child: Text("内容")),
    );
  }
}

跳转页面实现传参

class TimePag extends StatefulWidget {
  const TimePag({super.key});

  @override
  State<TimePag> createState() => _TimePagState();
}

class _TimePagState extends State<TimePag> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
            onPressed: () {
              Navigator.pushNamed(context, "/news",
                  arguments: {"title": "我是命名路由传的值", "id": 5}); //命名路由跳转
            },
            child: const Text("命名路由跳转传值"))
      ],
    );
  }
}

Flutter 中的命名路由单独抽离到一个文件

新建routers/routers.dart 配置路由

import 'package:app_flutter01/pages/form.dart';
import 'package:app_flutter01/pages/news.dart';
import 'package:app_flutter01/pages/tabs.dart';
import 'package:flutter/material.dart';


  //1.配置路由
  Map routes = {
    "/": (contxt) => const MyFlutter1(),
    "/form": (contxt) => const FormPage(),
    // "/news": (contxt)=>const SearchMyApp(),
    "/news": (contxt, {arguments}) {
      return SearchMyApp(arguments: arguments); //命名路由传参
    }, //类似
  };

// onGenerateRoute处理(固定写法)  这个方法也相当于一个中间件,这里可以做权限判断
  var 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;
          }
        }
        return null;
      };

修改main.dart

class MyApp1 extends StatelessWidget {
  MyApp1({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        appBarTheme: const AppBarTheme(
          color: Colors.blue, // 设置导航栏颜色 (新版本的设置方法)
        ),
      ),
      // home: Scaffold(body: MyFlutter1())
      initialRoute: "/", //初始化路由
      //2、调用onGenerateRoute处理(固定写法)
      onGenerateRoute: onGenerateRoute,
    );
  }
}

实现页面跳转传值

class TimePag extends StatefulWidget {
  const TimePag({super.key});

  @override
  State<TimePag> createState() => _TimePagState();
}

class _TimePagState extends State<TimePag> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
            onPressed: () {
              Navigator.pushNamed(context, "/news",
                  arguments: {"title": "我是命名路由传的值", "id": 5}); //命名路由跳转
            },
            child: const Text("命名路由跳转传值"))
      ],
    );
  }
}
Flutter 返回上一级路由
Navigator.of(context).pop();

Flutter 中替换路由

比如我们从用户中心页面跳转到了registerFirst页面,然后从registerFirst页面通过
pushReplacementNamed跳转到了registerSecond页面。这个时候当我们点击registerSecond的返回
按钮的时候它会直接返回到用户中心。
Navigator.of(context).pushReplacementNamed('/registerSecond');

Flutter 返回到根路由

比如我们从用户中心跳转到registerFirst页面,然后从registerFirst页面跳转到registerSecond页面,然
后从registerSecond跳转到了registerThird页面。这个时候我们想的是registerThird注册成功后返回到
用户中心。 这个时候就用到了返回到根路由的方法。
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (BuildContext context) {
return const Tabs();
}), (route) => false);

Flutter Android 和Ios使用同样风格的路由跳转

Material组件库中提供了一个MaterialPageRoute组件,它可以使用和平台风格一致的路由切换动画,
如在iOS上会左右滑动切换,而在Android上会上下滑动切换 , CupertinoPageRoute是Cupertino组件
库提供的iOS风格的路由切换组件如果在Android上也想使用左右切换风格,可以使用
CupertinoPageRoute。
import 'package:app_flutter01/pages/form.dart';
import 'package:app_flutter01/pages/news.dart';
import 'package:app_flutter01/pages/tabs.dart';
import 'package:flutter/material.dart';

//配置ios fen
import 'package:flutter/cupertino.dart';

/**
 配置ios风格的路由
1、删掉material.dart引入
cupertino.dartimport 'package:flutter/cupertino.dart';
2、把MaterialPageRoute替换成CupertinoPageRoute
 */

//1.配置路由
Map routes = {
  "/": (contxt) => const MyFlutter1(),
  "/form": (contxt) => const FormPage(),
  "/time": (contxt) => const MyFlutter1(),

  // "/news": (contxt)=>const SearchMyApp(),
  "/news": (contxt, {arguments}) {
    return SearchMyApp(arguments: arguments); //命名路由传参
  }, //类似
};

// onGenerateRoute处理(固定写法)  这个方法也相当于一个中间件,这里可以做权限判断
var onGenerateRoute = (RouteSettings settings) {
  // 统一处理
  final String? name = settings.name; //获取命名路由的名称
  final Function? pageContentBuilder = routes[name];
  if (pageContentBuilder != null) {
    if (settings.arguments != null) {
      // final Route route = MaterialPageRoute(  //路由效果
      final Route route = CupertinoPageRoute(
          builder: (context) =>
              pageContentBuilder(context, arguments: settings.arguments));
      return route;
    } else {
      final Route route =
          MaterialPageRoute(builder: (context) => pageContentBuilder(context));
      return route;
    }
  }
  return null;
};

全局配置主题

return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
appBarTheme: const AppBarTheme(
centerTitle: true,  //标题居中
)
),
initialRoute: "/",
onGenerateRoute: onGenerateRoute,
);