LOADING

MiniKano的小窝


 

flutter中的路由

路由(Route)在WEB开发中单页面应用里很常见,Flutter也有自己的路由,但是因为在Android系统中,Route指的是一个Activity 在IOS系统中指的是一个View Controller
路由管理就是使用路由栈进行push和pop的操作,将路由推入和弹出,入栈意味着打开一个新页面,出栈代表着关闭一个页面;除了使用路由栈之外,还需要其他的操作,例如路由拦截,路由重定向等。。

普通路由和路由跳转

1.创建一个名为MyText的新路由(可以进行参数传递)

class MyText extends StatefulWidget {
  //其他页面跳转到Form页面进行命名路由传值
  final Map arguments;
  const MyText({super.key, required this.arguments});

  @override
  State<MyText> createState() => _MyTextState();
}

class _MyTextState extends State<MyText> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Route"),
      ),
      body: Center(
        child: Text(widget.arguments.toString()),
      ),
    );
  }
}

2.在其他任意widget中使用该路由(需要提前import),这里使用ElevatedButton做演示,按钮点击后就会跳转到新路由(顺带传递参数)

//imported
ElevatedButton(
    onPressed: () {
        //路由
        //或者Navigator.push,视组件不同情况而定
        Navigator.of(context).push(
            MaterialPageRoute(
                builder: (BuildContext context) {
                    return const MyText(
                        arguments: {'kano': "kanokano.cn"},
                    );
                },
            ),
        );
    },
    child: const Text("搜索(路由跳转)"),
),

创建命名路由

注意:命名路由在新版Flutter文档中已经被标记为不建议使用

Although named routes can handle deep links, the behavior is always the same and can’t be customized. When a new deep link is received by the platform, Flutter pushes a new onto the Navigator regardless where the user currently is.Route

Flutter also doesn’t support the browser forward button for applications using named routes. For these reasons, we don’t recommend using named routes in most applications.

1.创建一个名为MyText的新路由(这里直接使用上面的MyText)

2.在main.dart中使用Tabs路由

import 'package:flutter/material.dart';
//普通组件
import './mytext.dart';

void main(List<String> args) {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "Test",
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      //1.初始化路由
      initialRoute: '/text1',
      //直接命名路由
      routes: {
        '/text1': (context) => const MyText(),
      },
    );
  }
}

3.路由跳转

ElevatedButton(
    onPressed: () {
        //路由
        Navigator.pushNamed(context, '/text1');
    },
    child: const Text("基本路由跳转text1"),
),

命名路由中的参数传递

总体来说就是这三步:

  1. 配置路由
  2. 初始化路由
  3. 配置onGenerateRouter
class MyApp extends StatelessWidget {
  //路由传参 - 1.配置路由 (可以单独提取出来作为routes.dart
  Map routes = {
    "/": (context) => const Tabs(),
    "/news": (context) => const NewsPage(),
    "/search": (context) => const NewsPage(),
    //带参数
    "/form": (context, {arguments}) {
      return FormPage(
        arguments: arguments,
      );
    },
    "/shop": (context, {arguments}) {
      return ShopPage(arguments: arguments);
    }
  };

  MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "Test",
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),

      //2.初始化路由
      initialRoute: '/',

      //路由传参-3.处理路由(也可以单独提取出来作为routes.dart
      //配置onGenerateRouter(我觉得这是一个拦截器)
      onGenerateRoute: (RouteSettings settings) {
        print(settings); //路由传值信息
        print(settings.arguments); //传的参数
        print(settings.name); //路由名
        final String? name = settings.name;
        final Function? pageCoutentBuilder = routes[name];
        if (pageCoutentBuilder != null) {
          //有参的情况
          if (settings.arguments != null) {
            final Route route = MaterialPageRoute(
              builder: (context) =>
                  pageCoutentBuilder(context, arguments: settings.arguments),
            );
            return route;
          } else {
            //无参的情况
            final Route route = MaterialPageRoute(
              builder: (context) => pageCoutentBuilder(context),
            );
            return route;
          }
        }
        return null;
      },
    );
  }
}

4.路由跳转附带传值

ElevatedButton(
    onPressed: () {
        //路由
        Navigator.pushNamed(context, '/form',arguments: {"kano": "kanokano"});
    },
    child: const Text("命名路由传值form"),
),

返回上一级路由

只需要使用

Navigator.pop(context);
//或者
Navigator.of(context).pop()

替换路由

当我们不想一步一步返回的时候,就可以使用路由的替换模式(跳转页面并销毁当前页面)

Navigator.of(context).pushReplacementNamed('/xxx')
//or
Navigator.pushReplacementNamed(context,'/xxx')

路由跳转风格设置

Material组件库中提供了一个MaterialPageRoute组件,它可以使用和平台风格一致的路由切换动画,如在iOS上会左右滑动切换,而在Android上会上下滑动切换,CupertinoPageRoute是Cupertino组件库提供的iOS风格的路由切换组件,如果在Android上也想使用左右切换风格,可以使用CupertinoPageRoute

1.引入

import 'package:flutter/cupertino.dart';

2.修改MaterialPageRouteCupertinoPageRoute

// import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_application_1/pages/form.dart';
import 'package:flutter_application_1/pages/news.dart';
import 'package:flutter_application_1/pages/tabs/shop.dart';
import '../pages/tabs.dart';

//路由传参 - 1.配置路由(可以单独提取出来作为routes.dart
Map routes = {
  "/": (context) => const Tabs(),
  "/news": (context) => const NewsPage(),
  "/search": (context) => const NewsPage(),
  //带参数
  "/form": (context, {arguments}) {
    return FormPage(
      arguments: arguments,
    );
  },
  "/shop": (context, {arguments}) {
    return ShopPage(arguments: arguments);
  }
};
var onGenerateRoute = (RouteSettings settings) {
  final String? name = settings.name;
  final Function? pageCoutentBuilder = routes[name];
  if (pageCoutentBuilder != null) {
    //有参
    if (settings.arguments != null) {
      final Route route = CupertinoPageRoute(
        builder: (context) =>
            pageCoutentBuilder(context, arguments: settings.arguments),
      );
      return route;
    } else {
      //无参
      final Route route = CupertinoPageRoute(
        builder: (context) => pageCoutentBuilder(context),
      );
      return route;
    }
  }
  return null;
};
点赞

发表回复

电子邮件地址不会被公开。必填项已用 * 标注