Flutter练习demo
路由分类
Flutter的路由就是指界面眺转,在Flutter中通过Navigator组件管理路由导航。
并提供了管理堆栈的方法。如:Navigator.push和Navigator.pop
总体来说分两种方式:
- 基本路由
- 命名路由
基本路由
效果图:
使用
代码
import 'package:flutter/material.dart';
/**
* 基本路由
* */
class RouteBasicDataPage extends StatefulWidget {
String title;
RouteBasicDataPage({this.title = "默认值:基本路由不传值"});
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return RouteDataContentPage(mTitle: title);
}
}
class RouteDataContentPage extends State {
String mTitle;
RouteDataContentPage({this.mTitle});
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.of(context).pop(),//返回上一级
child: Text("返回"),
),
appBar: AppBar(
title: Text(mTitle),
// leading: IconButton(
// onPressed: () => Navigator.of(context).pop(),
// icon: Container(
// child: Icon(
// Icons.arrow_back,
// color: Colors.cyanAccent,
// ),
// ),
// ),
),
body: Text(mTitle),
);
}
}
基本路由传参和不传参,这里还是简单的,请参考上方使用方式,和代码。
细心的朋友发现,跳转的结果界面即使你不加上AppBar的leading属性,系统会默认帮你加上的,当然这里是可以修改的,如下:
leading: IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: Container(
child: Icon(
Icons.arrow_back,
color: Colors.cyanAccent,
),
),
),
// 在自定义这个leading,点击时调用。 Navigator.of(context).pop(),是跟系统默认实现的效果是一样的
命名路由
命名路由,这里默认采用 路由分离(项目中更实用)
这里只介绍pushNamed以下这种方式:
Navigator.pushNamed(context, '/routeNamedPage');
路由分离
- 在main.dart中配置 initialRoute、onGenerateRoute
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
onGenerateRoute: onGenerateRoute,
);
}
}
- 路由配置抽离
import 'package:flutter/material.dart';
import 'RouteNamedPage.dart';
import 'package:cs_flutter/tab/BottomNvTabViewPage.dart';
final Map<String, Function> routes = {
'/': (contxt, {arguments}) => TabBootomNvPage(),
//arguments 参数可配置
"/routeNamedPage": (context, {arguments}) => RouteNamedPage(content: arguments)
};
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;
}
}
};
- 使用
- 参数接收
import 'package:flutter/material.dart';
/**
* 命名路由
* */
class RouteNamedPage extends StatefulWidget {
String content;
RouteNamedPage({this.content}) {
if (content == null) {
content = "命名路由默认值";
}
}
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return RouteNameContentPage(mArguments: content);
}
}
class RouteNameContentPage extends State {
String mArguments;
RouteNameContentPage({this.mArguments}) {
print(mArguments);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.of(context).pop(),
child: Text("返回"),
),
appBar: AppBar(
title: Text(mArguments),
),
body: Text(mArguments),
);
}
}
注 命名路由要跳转的界面构造方法接收数据时和基本理由的接收方式有点小区别,这里需要注意下:
命名路由,要跳转的界面构造接收数据:
// 命名路由
RouteNamedPage({this.content}) {
if (content == null) {
content = "命名路由默认值";
}
}
// 基本路由
RouteBasicDataPage({this.title = "默认值:基本路由不传值"});
命名路由方式跳转页面构造接收数据,不能按照基本路由的方式,因为当不传参数时this.content 是接收不到数据,像基本路由这种赋值默认值,是没有作用的,依旧是null
效果图:
返回上一级页面
Navigator.of(context).pop();
上面代码已展示
替换路由
Navigator.of(context).pushReplacementNamed('/registerSecond');
开发中这种场景很常见:
当前界面是A,要跳转B页面,B页在跳转C界面,C界面的某个操作完成后直接展示的是A界面(C界面的某个操作完成后B、C直接关闭了)。这个时候无论是自定义返回Navigator.of(context).pop();
,还是系统默认实现的返回 ,是达不到这种效果的。
在B跳转C界面时要用Navigator.pushReplacementNamed(context, '/routeC_Page');
不要用Navigator.pushNamed(context, '/routeC_Page');
效果:
返回到根路由
- 主页定义构造接收参数、路由配置
// 路由配置,参数可传可不传
final Map<String, Function> routes = {
'/': (contxt, {arguments}) => TabBootomNvPage(index: arguments),
};
class TabBootomNvPage extends StatefulWidget {
int index;
TabBootomNvPage({this.index}) {
if (index == null) {
index = 0;//必须要加,不然会为null
}
}
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return BootomNvPage(currentIndex: this.index);
}
}
class BootomNvPage extends State {
int currentIndex = 0;
BootomNvPage({this.currentIndex});
..... 省略N行代码
}
2.C界面点击某个按钮时,指定到主页的当前模块或者其他模块等
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(
//TabBootomNvPage index 主页的构造方法接收,返回根路由,也可以指定展示对应的Tab模块 , index代表主页模块的下标
builder: (context) => new TabBootomNvPage(index: 2)),
(route) => route == null);
效果:
关于路由跳转这一块的方法,flutter提供的还有很多方法,可自行尝试!