Flutter路由

基本路由

比如当我们现在想从a组件跳转到b组件

  • 1,需要在a组件中引入b组件
  • 2,在a页面中通过下面方法跳转

main主页面

import 'package:flutter/material.dart';
import './路由跳转/a.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: "万物互联",
        home: Scaffold(
          appBar: AppBar(
              title: Text('App标题'),
              backgroundColor: const Color.fromARGB(255, 70, 83, 219)),
          body: APage(),
        ));
  }
}

a 页面

import 'package:flutter/material.dart';
import './b.dart';

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

  @override
  State<APage> createState() => _APageState();
}

class _APageState extends State<APage> {
  @override
  Widget build(BuildContext context) {
    // 横向居中
    return Center(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.center, // 竖向居中
      children: [
        ElevatedButton(
          onPressed: () {
            //跳转路由
            Navigator.of(context).push(MaterialPageRoute(builder: (context) {
              return BPage();
            }));
          },
          child: Text('A页面跳转按钮'),
        )
      ],
    ));
  }
}

b页面

import 'package:flutter/material.dart';

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

  @override
  State<BPage> createState() => _BPageState();
}

class _BPageState extends State<BPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Text('B页面'),
          backgroundColor: const Color.fromARGB(255, 70, 83, 219)),
      body: Center(
        child: Text('B页面'),
      ),
    );
  }
}
基本路由跳转传值
  • a页面
 ElevatedButton(
          onPressed: () {
            //跳转路由-基本路由
            Navigator.of(context).push(MaterialPageRoute(builder: (context) {
              return CPage(
                title: 'c页面标题',
                type: '1',
              );
            }));
          },
          child: Text('A页面跳转c页面传值'),
        )
  • c页面
import 'package:flutter/material.dart';

class CPage extends StatefulWidget {
  final String title;
  final String type;
  const CPage({super.key, required this.title, this.type = '0'});

  @override
  State<CPage> createState() => _CPageState();
}

class _CPageState extends State<CPage> {
  //生命周期函数中打印
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    print(widget.type);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          //获取定义的title
          title: Text(widget.title),
          backgroundColor: const Color.fromARGB(255, 70, 83, 219)),
      body: Center(
        child: Text('C页面'),
      ),
    );
  }
}
命名路由
  • 基本路由适用普通项目跳转
  • 但项目大的时候,希望有个地方统一管理路由,采用命名路由
import 'package:flutter/material.dart';

import './a.dart';
import './b.dart';
import './c.dart';

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

  @override
  State<RouterList> createState() => __RouterLiStateState();
}

//所有路由配置除
class __RouterLiStateState extends State<RouterList> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(title: '路由列表', 
    //初始化路由
    initialRoute: '/', 
    //命名路由
    routes: {
      '/': (contxt) => const APage(),
      '/b': (contxt) => const BPage(),
      '/c': (contxt) => const CPage(
            title: 'c标题',
          ),
    });
  }
}

命名路由传参
  • main页面
import 'package:flutter/material.dart';
import './路由跳转/routerTitle.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: "万物互联",
        home: Scaffold(
          appBar: AppBar(
              title: Text('App标题'),
              backgroundColor: const Color.fromARGB(255, 70, 83, 219)),
          body: RouterPage(),
        ));
  }
}

  • 路由集合页面
  • arguments是命名路由传递参数
import 'package:flutter/material.dart';

import './a.dart';
import './b.dart';
import './c.dart';
import 'home.dart';
import 'formPage.dart';

// ignore: must_be_immutable
class RouterPage extends StatelessWidget {
  // 1,定义配置路由
  Map routes = {
    '/': (contxt) => HomePage(),
    '/a': (contxt) => const APage(),
    '/b': (contxt) => const BPage(),
    '/c': (contxt) => const CPage(
          title: 'c标题',
        ),
    '/formPage': (contxt, {arguments}) => formPage(arguments: arguments),
  };
  RouterPage({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: '路由列表',
        initialRoute: '/',
        //2,配置onGenerateRoute(固定写法)
        onGenerateRoute: (RouteSettings settings) {
          print(settings);
          //要跳转的页面路径
          print(settings.name);
          //要跳转的页面传参
          print(settings.arguments);
          //因为 settings.name是可读参数,所以前面也得定义成可读参数
          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;
        },
        routes: {});
  }
}

  • 配置的默认页面HomePage
import 'package:flutter/material.dart';

//其它路由跳转到当前页面进行命名路由传值
class HomePage extends StatefulWidget {
  @override
  State<HomePage> createState() => __FormPagStateState();
}

class __FormPagStateState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center, // 竖向居中
          children: [
            ElevatedButton(
              onPressed: () {
                Navigator.pushNamed(context, '/c');
              },
              child: Text('命名路由跳转传值'),
            ),
            ElevatedButton(
              onPressed: () {
                Navigator.pushNamed(context, '/formPage',
                    arguments: {'title': "我是命名路由传值", 'type': 20});
              },
              child: Text('命名路由跳转formPage'),
            ),
          ],
        ),
      ),
    );
  }
}

  • 配置的要跳转的页面formPage
import 'package:flutter/material.dart';

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

  @override
  State<formPage> createState() => __FormPagStateState();
}

class __FormPagStateState extends State<formPage> {
  @override
  void initState() {
    super.initState();
    //打印传递的参数
    print(widget.arguments);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text('接收参数页面')
    );
  }
}

路由封装
  • router文件
import 'package:flutter/material.dart';

import '../路由跳转/a.dart';
import '../路由跳转/b.dart';
import '../路由跳转/c.dart';
import '../路由跳转/home.dart';
import '../路由跳转/formPage.dart';

// 1,定义配置路由
Map routes = {
  '/': (contxt) => HomePage(),
  '/a': (contxt) => const APage(),
  '/b': (contxt) => const BPage(),
  '/c': (contxt) => const CPage(
        title: 'c标题',
      ),
  '/formPage': (contxt, {arguments}) => formPage(arguments: arguments),
};
// 2,配置onGenerateRoute
var onGenerateRoute = (RouteSettings settings) {
  //因为 settings.name是可读参数,所以前面也得定义成可读参数
  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/router.dart';

class RouterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '路由列表',
      initialRoute: '/',
      onGenerateRoute: onGenerateRoute,
    );
  }
}

Flutter返回上级路由
 Navigator.of(context).pop()
Flutter替换路由
  • 当我们从A-B-C,使C返回的时候直接到A
 Navigator.of(context).pushReplacementNamed('/c')
Flutter返回根路由
 //返回根路由
 Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (BuildContext context){
    return HomePage();
 }),(route)=>false)
设置Android和ios使用同样风格的路由跳转
  • Material组件库提供了MaterialPageRoute组件,可以是平台风格保持一致的路由切换动画
  • 例如,ios是左右滑动,andriod是上下滑动
  • 而我想让andro也左右滑动
配置ios风格路由切换
  • 步骤1,router页面,删除material,引入cupertino
// import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
  • 步骤2:MaterialPageRoute修改为CupertinoPageRoute
    在这里插入图片描述

Flutter的Dialog

AlertDialog

在这里插入图片描述

 void _alertDialog() async {
    print('_alertDialog');
    var result = await showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text('aleart组件提示信息'),
            content: Text("您确定要删除吗"),
            //按钮组
            actions: [
              TextButton(
                  onPressed: () {
                    print('ok');
                    //关闭弹窗
                    Navigator.of(context).pop(1);
                  },
                  child: Text('确定')),
              TextButton(
                  onPressed: () {
                    print('no');
                    Navigator.of(context).pop(2);
                  },
                  child: Text('取消'))
            ],
          );
        });
    //通过async/await可获取点击弹窗按钮的值1/2
    print(result);
  }

SimpleDialog

在这里插入图片描述

void _selectDialog() async {
    print('_selectDialog');
    var result = await showDialog(
        //点击灰色背景是否消失弹窗框
        barrierDismissible: true,
        context: context,
        builder: (context) {
          return SimpleDialog(
            title: Text('请选择内容'),
            //按钮组
            children: [
              SimpleDialogOption(
                onPressed: () {
                  print("option1");
                  //写法2
                  Navigator.pop(context, 'a');
                },
                child: Text('option1'),
              ),
              Divider(),
              SimpleDialogOption(
                onPressed: () {
                  print("option2");
                  Navigator.pop(context, 'b');
                },
                child: Text('option2'),
              )
            ],
          );
        });
    print(result);
  }
showModalBottomSheet

在这里插入图片描述

 void _ActionBottomDialog() async {
    var result = await showModalBottomSheet(
        context: context,
        builder: (context) {
          return Container(
            height: 300,
            padding: EdgeInsets.all(12),
            child: Column(
              children: [
                ListTile(
                  title: Text('分享'),
                  onTap: () {
                    print('点击事件');
                    Navigator.pop(context, '分享');
                  },
                ),
                Divider(),
                ListTile(
                  title: Text('收藏'),
                ),
                Divider(),
                ListTile(
                  title: Text('取消'),
                ),
                Divider(),
                ListTile(
                  title: Text('文本1'),
                )
              ],
            ),
          );
        });
    print(result);
  }

fluttertoast
  • 组件网站
  • 如何导入组件
  • 方式1
  • flutter pub add fluttertoast
  • 方式2
    在这里插入图片描述
  • 然后保存即可自动下载,(自动执行flutter pub get)
  • 然后按照文档页面使用即可

在这里插入图片描述

  void _toast() {
    Fluttertoast.showToast(
        msg: "This is Center Short Toast",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
        timeInSecForIosWeb: 1,
        backgroundColor: Colors.red,
        textColor: Colors.white,
        fontSize: 16.0);
  }

自定义Dialog

  • dialog页面
import 'package:flutter/material.dart';

// 首先需要继承Dialog
class MyDialog extends Dialog {
  //自定义传值
  final String title;
  final String content;
  //可控类型
  final Function()? onTap;
  const MyDialog(
      {Key? key,
      required this.title,
      required this.content,
      required this.onTap})
      : super(key: key);
  Widget build(BuildContext context) {
    //可以return任何组件,建议Material组件
    return Material(
        //设置背景透明
        type: MaterialType.transparency,
        child: Center(
          // 注意要包裹一个组件,不然会全屏
          child: Container(
            height: 300,
            width: 200,
            color: Colors.white,
            child: Column(
              children: [
                Padding(
                  padding: EdgeInsets.all(12),
                  child: Stack(
                    children: [
                      Align(
                        alignment: Alignment.centerLeft,
                        child: Text(title),
                      ),
                      Align(
                        alignment: Alignment.centerRight,
                        child: InkWell(
                          onTap: onTap,
                          child: Icon(Icons.close),
                        ),
                      )
                    ],
                  ),
                ),
                Divider(),
                Container(
                  padding: EdgeInsets.all(12),
                  // 宽度是外侧宽度
                  width: double.infinity,
                  child: Text(content),
                ),
              ],
            ),
          ),
        ));
  }
}

  • 使用页面
import '../widegt/dialog.dart';
//方法体
  void _myDialog() {
    print("_myDialog");
    //自定义组件包裹在showDialog里面
    var result = showDialog(
        // 点击灰色背景是否消失弹出框
        barrierDismissible: false,
        context: context,
        builder: (context) {
          return MyDialog(
            title: '自定义提示',
            content: '自定义内容',
            onTap: () {
              Navigator.pop(context, '返值给result');
              print('关闭');
            },
          );
        });
    print(result);
  }
//使用的时候
ElevatedButton(onPressed: _myDialog, child: Text('自定义Dialog'))
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐