Flutter 之路由

2023-10-15  本文已影响0人  Abner_XuanYuan

1、路由介绍

Flutter 中的路由通俗的讲就是页面跳转。在 Flutter 中通过 Navigator 组件管理路由导航。并提供了管理堆栈的方法。如:Navigator.push 和 Navigator.pop。
Flutter 中给我们提供了两种配置路由跳转的方式:1、基本路由 2、命名路由。

2、普通路由

例:从 HomePage 组件跳转到 SearchPage 组件。
1、需要在 HomPage 中引入 SearchPage.dart

import './testLib/SearchPage.dart';

2、在 HomePage 中跳转

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("页面跳转"),
      ),
      backgroundColor: Colors.grey,
      body: Center(
        child: ElevatedButton(
            onPressed: () {
              //通过以下方法实现跳转
              Navigator.of(context).push(MaterialPageRoute(builder: (context) {
                return const SearchPage();
              }));
            },
            child: const Text("页面跳转按钮")),
      ),
    );
  }
}

传值
1、SearchPage 页面

import 'package:flutter/material.dart';

class SearchPage extends StatelessWidget {
  final String title;

  const SearchPage({super.key, this.title = "Search"});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.orange,
      appBar: AppBar(
        title: Text(title),
        centerTitle: true,
      ),
      body: Center(
        child: Container(
          color: Colors.green,
          child: const Text("搜索页面视图"),
        ),
      ),
    );
  }
}

2、HomePage 页面

// 以下为传值时的代码
class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("页面跳转"),
      ),
      backgroundColor: Colors.grey,
      body: Center(
        child: ElevatedButton(
            onPressed: () {
              //通过以下方法实现跳转
              Navigator.of(context).push(MaterialPageRoute(builder: (context) {
                // return const SearchPage();
                return const SearchPage(title: "搜索vvvvv",);  //传值
              }));
            },
            child: const Text("页面跳转按钮")),
      ),
    );
  }
}

3、命名路由

1、无参跳转

配置 routes

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

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      // home: HomePage(),
     initialRoute: '/',    //初始化路由
      routes: {     //跳转路由(更改建议:调整为路由表)
        '/':(contxt)=>const Tabs(), 
        '/search':(contxt) => const SearchPage(), 
        '/form': (context) => const FormPage(), },
    );
  }
}

跳转

ElevatedButton(
            onPressed: () {
              Navigator.pushNamed(context, '/form');
            },
            child: const Text("跳转到form页面")),
2、有参跳转

配置 onGenerateRoute

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


void main() { 
  runApp(const MyApp()); 
  }
  
  class MyApp extends StatelessWidget {
     //1、定义Map类型的routes 
     Map routes = { 
      '/': (contxt) => const Tabs(), 
      '/search': (contxt) => const SearchPage(),      //注意:命名路由无需传值方式
      '/form': (context, {arguments}) => FormPage(arguments: arguments),     //注意:命名路由需要传值方式
      };
      MyApp({Key? key}) : super(key: key); 
      @override Widget build(BuildContext context) { 
        return MaterialApp( 
          debugShowCheckedModeBanner: false, 
          title: 'Flutter Demo', 
          theme: ThemeData( 
            primarySwatch: Colors.blue, 
            ),
            initialRoute: '/',     //初始化路由
            //2、配置 onGenerateRoute
            onGenerateRoute: (RouteSettings settings) { 
              // 统一处理 
              final String? name = settings.name;     //路由名称,如:/form
              final Function? pageContentBuilder = routes[name];     // Function,如:(contxt) => const SearchPage()
              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 参数

import 'package:flutter/material.dart'; 
class FormPage extends StatefulWidget { 
  final Map arguments;     //接收参数
  const FormPage({super.key,required this.arguments}); 
  
  @override 
  State<FormPage> createState() => _FormPageState(); 
}

class _FormPageState extends State<FormPage> { 
  @override 
  void initState() {
     print(widget.arguments); 
  }
  
  @override 
  Widget build(BuildContext context) { 
    return Scaffold( 
      appBar: AppBar( 
        title: const Text("我是一个Form表单演示页面"), 
      ), 
    ); 
  } 
}

跳转

ElevatedButton(
  onPressed: () { 
    Navigator.pushNamed(context, '/form',arguments: {     //传参
      "title": "搜索页面", 
    }); 
  },
   child: const Text("form") 
)
3、命名路由方法封装

在路由文件中配置公共路由和 onGenerateRoute

//1、导入头文件
import 'package:flutter/material.dart';
import '../pages/tabs.dart';
import '../pages/search.dart';
import '../pages/news.dart';
import '../pages/form.dart';
import '../pages/shop.dart';

//2、配置路由(路由中字符串(key)可以进一步进行宏定义封装)
Map routes = {
  "/": (contxt) => const Tabs(),
  "/news": (contxt) => const NewsPage(),
  "/search": (contxt) => const SearchPage(),
  "/form": (contxt, {arguments}) => FormPage(arguments: arguments),
  "/shop": (contxt, {arguments}) => ShopPage(arguments: arguments),
};

//3、配置 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;
};

路由跳转配置

import 'package:flutter/material.dart';
import './routers/routers.dart';  //导入路由文件

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      //路由跳转
      initialRoute: "/",    //初始化路由
      onGenerateRoute: onGenerateRoute,   //路由跳转
    );
  }
}

使用

//无参
ElevatedButton(
              onPressed: () {
                Navigator.pushNamed(context, "/news");
              },
              child: const Text("命名路由跳转news")),
//有参
ElevatedButton(
              onPressed: () {
                Navigator.pushNamed(context, "/shop",
                    arguments: {"title": "shop传值", "aid": 21});
              },
              child: const Text("命名路由传值Shop")),

4、路由相关方法

返回上一级路由

Navigator.of(context).pop();

路由替换:跳转到指定页面

Navigator.of(context).pushReplacementNamed('/registerSecond');

返回到根路由

Navigator.of(context).pushAndRemoveUntil( 
  MaterialPageRoute(builder: (BuildContext context) { 
    return const Tabs(); 
  }), (route) => false);

路由跳转风格
Material 组件库中提供了一个 MaterialPageRoute 组件,它可以使用和平台风格一致的路由切换动画,如在 iOS 平台上会左右滑动切换,而在 Android 上会上下滑动切换 。CupertinoPageRoute 是 Cupertino 组件库提供的 iOS 风格的路由切换组件如果在 Android 上也想使用左右切换风格,可以使用 CupertinoPageRoute。
使用方法
1、引入 cupertino.dart

import 'package:flutter/cupertino.dart';

2、MaterialPageRoute 改为 CupertinoPageRoute

///测试示例
import 'package:flutter/cupertino.dart';     //注意:引入头文件
import '../pages/tabs.dart'; 
import '../pages/shop.dart'; 
import '../pages/user/login.dart'; 
import '../pages/user/registerFirst.dart'; 
import '../pages/user/registerSecond.dart'; 
import '../pages/user/registerThird.dart'; 

//1、配置路由 
Map routes = { 
  "/": (contxt) => const Tabs(), 
  "/login": (contxt) => const LoginPage(),
  "/registerFirst": (contxt) => const RegisterFirstPage(), 
  "/registerSecond": (contxt) => const RegisterSecondPage(), 
  "/registerThird": (contxt) => const RegisterThirdPage(), 
  "/shop": (contxt, {arguments}) => ShopPage(arguments: arguments), 
  };
  
//2、配置onGenerateRoute 固定写法 这个方法也相当于一个中间件,这里可以做权限判断 
var onGenerateRoute = (RouteSettings settings) { 
  final String? name = settings.name; // /news 或者 /search 
  final Function? pageContentBuilder = routes[name]; 
Function = (contxt) { return const NewsPage()} 

  if (pageContentBuilder != null) { 
    if (settings.arguments != null) { 
      final Route route = CupertinoPageRoute(     //MaterialPageRoute 改为 CupertinoPageRoute
        builder: (context) => 
            pageContentBuilder(context, arguments: settings.arguments)); 
      return route; 
    } else { 
      final Route route = 
        CupertinoPageRoute(builder: (context) => pageContentBuilder(context));     //MaterialPageRoute 改为 CupertinoPageRoute
      return route; 
    } 
  }
  return null; 
};
上一篇下一篇

猜你喜欢

热点阅读