banner
MiniKano

MiniKano

This is MiniKano's blog based on Blockchain technology. 新手,请多关照~
github

Flutter 路由配置

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;
};
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.