Flutter - 路由管理 - 02 - Fluro,12年高级工程师的“飞升之路”

文章详细描述了使用Flutter构建应用时,如何设置启动页的Splash跳转至Home页面,以及如何处理参数传递,包括String、int、double、bool和自定义类型。作者还介绍了FluroConvertUtils工具类用于参数编码和解码。
摘要由CSDN通过智能技术生成

runApp(MyApp());
}

4. my_app.dart

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: ‘Weather App’,
/// 生成路由
onGenerateRoute: Application.router.generator,
);
}
}

3. 场景一:设置启动页 Splash 跳转到 Home页面,并且移除 Splash 页面

只摘取相关代码,完整代码去 github查看,在文章最顶部

首先App启动,先进入 首页Splash 页面,然后 倒计时2秒,再进入home页面

1. 效果图

1. 首先先打开 Splash 页面

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. 两秒后跳转到 home 页面

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. 代码

1. routes.dart

/// 这边设置了首页,固定写法 /
static String root = “/”;
/// home 页面的 路由地址
static String home = “/home”;

/// splashHandler 就是页面跳转,在route_handlers.dart
router.define(root, handler: splashHandler);
/// homeHandler home页面
router.define(home, handler: homeHandler);

2. route_handlers.dart

/// 跳转到首页Splash
var splashHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List> params) {
return new SplashPag();
});

/// 跳转到主页
var homeHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List> params) {
return HomePage();
});

3. splash_page.dart

class SplashPag extends StatefulWidget {
@override
_SplashPagState createState() => _SplashPagState();
}

class _SplashPagState extends State {

@override
void initState() {
// Future.delayed(Duration(seconds: 5),(){
// NavigatorUtil.goHomePage(context);
// });
/// 2秒后跳转到主页面,上面注释的代码也可以做到倒计时
Observable.timer(0, Duration(seconds: 2)).listen((_){
/// 然后看 NavigatorUtil.dart
NavigatorUtil.goHomePage(context);
});
super.initState();
}

@override
Widget build(BuildContext context) {

return Scaffold(
body: Center(
child: Container(
child: Text(‘我是欢迎页面’),
),
),
);
}
}

4. NavigatorUtil.dart

/// 跳转到主页面
static void goHomePage(BuildContext context) {
/// Routes.home 路由地址
/// replace:true 就是将 splash 页面给移除掉了,这点后退键的时候就不会再出现Splash页面
Application.router.navigateTo(context, Routes.home, replace: true);
}

5. home_page.dart

class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}

class _HomePageState extends State {
@override
Widget build(BuildContext context) {
String name = “来自第一个界面测试一下”;
int age = 14;
double score = 6.4;
bool sex = true;
Person person = new Person(name: ‘Zeking’, age: 18, sex: true);

return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(child: Text(‘这是主页’)),
RaisedButton(
child: Text(‘传递参数string ,int,double,bool ,自定义类型’),
onPressed: () {
NavigatorUtil.goDemoParamsPage(
context, name, age, score, sex, person);
},
),
RaisedButton(
child: Text(‘传递参数,接受返回值’),
onPressed: () {
NavigatorUtil.goReturnParamsPage(context).then((result) {
debugPrint(‘KaTeX parse error: Expected '}', got 'EOF' at end of input: …); debugPrint('{result.toJson().toString()}’);
} else {
message = ‘ r e s u l t ′ ; d e b u g P r i n t ( ′ result'; debugPrint(' result;debugPrint(result’);
}
showResultDialog(context, message);
});
},
),
RaisedButton(
child: Text(‘框架 自带 转场动画 演示’),
onPressed: () {
NavigatorUtil.gotransitionDemoPage(context,
/// 这边进行了 String 编码
FluroConvertUtils.fluroCnParamsEncode("框架 自带 转场动画 演示 \n\n\n "
"这边只展示 inFromLeft ,剩下的自己去尝试下,\n\n\n "
“架自带的有 native,nativeModal,inFromLeft,inFromRight,inFromBottom,fadeIn,custom”));
},
),
RaisedButton(
child: Text(‘框架 自定义 转场动画 演示’),
onPressed: () {
NavigatorUtil.gotransitionCustomDemoPage(context,
FluroConvertUtils.fluroCnParamsEncode(‘框架 自定义 转场动画 演示’));
},
),
RaisedButton(
child: Text(‘修改源码,添加使用 Flutter 的 cupertino 转场动画’),
onPressed: () {
NavigatorUtil.gotransitionCupertinoDemoPage(
context,
FluroConvertUtils.fluroCnParamsEncode(
“修改源码,添加使用 Flutter 的 cupertino 转场动画”));
},
),
],
),
);
}

/// 显示一个Dialgo
void showResultDialog(BuildContext context,String message){
showDialog(
context: context,
builder: (context) {
return new AlertDialog(
title: new Text(
“Hey Hey!”,
style: new TextStyle(
color: const Color(0xFF00D6F7),
fontFamily: “Lazer84”,
fontSize: 22.0,
),
),
content: new Text(“$message”),
actions: [
new Padding(
padding: new EdgeInsets.only(bottom: 8.0, right: 8.0),
child: new FlatButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: new Text(“OK”),
),
),
],
);
},
);
}
}

4. 场景二:传参 String,int,double,bool,自定义类型

1. 效果图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. 代码

1. 注意点(类型转换 fluro_convert_util.dart)

Fluro路由地址,只能传递String类型(并且不支持中文),所以需要对 中文,int,double,bool,自定义类型进行一个转换 , 写了一个 转换类 fluro_convert_util.dart

import ‘dart:convert’;

/// fluro 参数编码解码工具类
class FluroConvertUtils {
/// fluro 传递中文参数前,先转换,fluro 不支持中文传递
static String fluroCnParamsEncode(String originalCn) {
return jsonEncode(Utf8Encoder().convert(originalCn));
}

/// fluro 传递后取出参数,解析
static String fluroCnParamsDecode(String encodeCn) {
var list = List();

///字符串解码
jsonDecode(encodeCn).forEach(list.add);
String value = Utf8Decoder().convert(list);
return value;
}

/// string 转为 int
static int string2int(String str) {
return int.parse(str);
}

/// string 转为 double
static double string2double(String str) {
return double.parse(str);
}

/// string 转为 bool
static bool string2bool(String str) {
if (str == ‘true’) {
return true;
} else {
return false;
}
}

/// object 转为 string json
static String object2string(T t) {
return fluroCnParamsEncode(jsonEncode(t));
}

/// string json 转为 map
static Map<String, dynamic> string2map(String str) {
return json.decode(fluroCnParamsDecode(str));
}
}

2. Person.dart 等下用到的自定义类型

class Person{
String name;
int age;
bool sex;

Person({this.name, this.age,this.sex});

Person.fromJson(Map<String, dynamic> json) {
name = json[‘name’];
age = json[‘age’];
sex = json[‘sex’];
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data[‘name’] = this.name;
data[‘age’] = this.age;
data[‘sex’] = this.sex;
return data;
}
}

3. routes.dart

/// 配置路由地址 和 跳转类和参数handler
static String demoParams = “/deme_params”;

router.define(demoParams, handler: demoParamHandler);

4. route_handlers.dart

/// 参数传递 int ,double,bool,自定义类型
var demoParamHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List> params) {
/// params[“name”]?.first 相当于 params[“name”][0] ,打个debug 你就知道为什么了是个list
String name = params[“name”]?.first;
String age = params[“age”]?.first;
String sex = params[“sex”]?.first;
String score = params[“score”]?.first;
String personjson = params[‘personjson’]?.first;
/// 下面转换为真实想要的类型
return DemoParamsPage(
name: name,
age: FluroConvertUtils.string2int(age),
score: FluroConvertUtils.string2double(score),
sex: FluroConvertUtils.string2bool(sex),
personJson: personjson,
);
});

5. NavigatorUtil.dart

/// 跳转到 传参demo 页面
static void goDemoParamsPage(BuildContext context, String name, int age,
double score, bool sex, Person person) {
/// 对中文进行编码
String mName = FluroConvertUtils.fluroCnParamsEncode(name);
/// 对自定义类型 转为 json string
String personJson = FluroConvertUtils.object2string(person);
Application.router.navigateTo(
context,
Routes.demoParams +
“?name=KaTeX parse error: Expected 'EOF', got '&' at position 5: name&̲age=age&score=KaTeX parse error: Expected 'EOF', got '&' at position 6: score&̲sex=sex&personjson=$personJson”);
}

6. home_page.dart 跳转按钮

String name = “来自第一个界面测试一下”;
int age = 14;
double score = 6.4;
bool sex = true;
Person person = new Person(name: ‘Zeking’, age: 18, sex: true);

RaisedButton(
child: Text(‘传递参数string ,int,double,bool ,自定义类型’),
onPressed: () {
NavigatorUtil.goDemoParamsPage(
context, name, age, score, sex, person);
},
),

7. demo_params_pag.dart

class DemoParamsPage extends StatefulWidget {
final String name;
final int age;
final double score;
final bool sex;
final String personJson;

DemoParamsPage({this.name, this.age, this.score, this.sex, this.personJson});

@override
_DemoParamsPageState createState() => _DemoParamsPageState();
}

class _DemoParamsPageState extends State {
@override
Widget build(BuildContext context) {
/// 对 中文 进行解码
String mName = FluroConvertUtils.fluroCnParamsDecode(widget.name);
/// 对自定义类 进行解析
Person person =
Person.fromJson(FluroConvertUtils.string2map(widget.personJson));
print(person.name);
print(person.age);
print(person.sex);
/// 下面的写法也可以
Map<String, dynamic> data = FluroConvertUtils.string2map(widget.personJson);
print(data[“name”]);
print(data[“age”]);
print(data[“sex”]);

return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(‘name: m N a m e ′ ) , T e x t ( ′ a g e : mName'), Text('age: mName),Text(age{widget.age}’),
Text(‘score: w i d g e t . s c o r e ′ ) , T e x t ( ′ s e x : {widget.score}'), Text('sex: widget.score),Text(sex{widget.sex}’),
Text(‘Person:${person.toJson().toString()}’),
RaisedButton(
child: Text(‘返回’),
onPressed: () {
NavigatorUtil.goBack(context);
},
)
],
),
),
);
}
}

5. 场景三:接收返回值 String,int,double,自定义类型

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后

这里我特地整理了一份《Android开发核心知识点笔记》,里面就包含了自定义View相关的内容

如果你有需要的话,可以私信我【进阶】发给你

除了这份笔记,还给大家分享 Android学习PDF+架构视频+面试文档+源码笔记,高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这几块的内容。非常适合近期有面试和想在技术道路上继续精进的朋友。

如果你有需要的话,可以点击我的GitHub免费获取!

分享上面这些资源,希望可以帮助到大家提升进阶,如果你觉得还算有用的话,不妨把它们推荐给你的朋友~

**
[外链图片转存中…(img-wdOA6kCY-1711181779022)]

最后

这里我特地整理了一份《Android开发核心知识点笔记》,里面就包含了自定义View相关的内容

如果你有需要的话,可以私信我【进阶】发给你

[外链图片转存中…(img-NyIw5TiW-1711181779022)]

除了这份笔记,还给大家分享 Android学习PDF+架构视频+面试文档+源码笔记,高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这几块的内容。非常适合近期有面试和想在技术道路上继续精进的朋友。

如果你有需要的话,可以点击我的GitHub免费获取!

[外链图片转存中…(img-BvbD6RbT-1711181779023)]

分享上面这些资源,希望可以帮助到大家提升进阶,如果你觉得还算有用的话,不妨把它们推荐给你的朋友~

喜欢本文的话,给我点个小赞、评论区留言或者转发支持一下呗~

  • 28
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值