简单示例-跳转页面
import 'package:flutter/material.dart';
import 'dart:ui';
// import 'package:flutter/cupertino.dart';
// void main() {
// runApp(const MyApp());
// }
void main() => runApp(const MyApp());
// void main() => runApp(CupertinoApp(home: CupertinoTestRoute()));
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("路由-计数器例子"),
backgroundColor: Colors.green,
),
body: Center(
child: Page1(),
),
);
// return CounterWidget();
}
}
class Page1 extends StatefulWidget {
Page1({Key? key}) : super(key: key);
@override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
// print("build");
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineLarge,
),
TextButton(
style: TextButton.styleFrom(
foregroundColor: Colors.white, /// 按钮文字颜色
backgroundColor: Colors.blue,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return NewRoute();
}),
);
},
child: Text('跳转到新页面')),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class NewRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('路由跳转页面'),
),
body: Center(
child: Text('这是新的页面!'),
),
);
}
}
MaterialPageRoute
MaterialPageRoute({
WidgetBuilder builder, // 构建路由页面的具体内容,返回值是一个widget
RouteSettings settings, // 路由的配置信息,如路由名称、是否初始路由(首页)
bool maintainState = true, // 默认情况下,当入栈一个新路由时,原来的路由仍然会被保存在内存中,如果想在路由没用的时候释放其所占用的所有资源,可以设置maintainState为 false
bool fullscreenDialog = false, // 表示新的路由页面是否是一个全屏的模态对话框,在 iOS 中,如果fullscreenDialog为true,新页面将会从屏幕底部滑入(而不是水平方向)
})
Navigator
Navigator是一个路由管理的组件,它提供了打开和退出路由页方法。Navigator通过一个栈来管理活动路由集合。通常当前屏幕显示的页面就是栈顶的路由
- 入栈(即打开新的页面):Future push(BuildContext context, Route route)
- 出栈:bool pop(BuildContext context, [ result ]),result 为页面关闭时返回给上一个页面的数据。
- 其他方法:Navigator.replace、Navigator.popUntil
Navigator.push(BuildContext context, Route route)等价于Navigator.of(context).push(Route route)
路由传值
两个传值方式:
- 页面1(旧页面)跳转到页面2(新页面)时,将数据传递到页面2(新页面),页面2需要定义这个参数、接收参数
- 页面2(新页面)返回到页面1(旧页面)时,将数据返回页面1(旧页面),主要使用() => Navigator.pop(context, "这个数据是新页面传递给旧页面的"),其中第二个参数,会返回给页面1的result(如下)
var result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return TipRoute(
// 路由参数
text: "这个数据是旧页面传递给新页面的",
);
},
),
);
import 'package:flutter/material.dart';
import 'dart:ui';
// import 'package:flutter/cupertino.dart';
// void main() {
// runApp(const MyApp());
// }
void main() => runApp(const MyApp());
// void main() => runApp(CupertinoApp(home: CupertinoTestRoute()));
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: RouterTestRoute(),
);
}
}
class TipRoute extends StatelessWidget {
TipRoute({
Key? key,
required this.text, // 接收一个text参数
}) : super(key: key);
final String text;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("提示"),
),
body: Padding(
padding: EdgeInsets.all(18),
child: Center(
child: Column(
children: <Widget>[
Text(text),
ElevatedButton(
onPressed: () => Navigator.pop(context, "这个数据是新页面传递给旧页面的"),
child: Text("返回"),
)
],
),
),
),
);
}
}
class RouterTestRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("初始页面"),
),
body: Center(
child: ElevatedButton(
onPressed: () async {
// 打开`TipRoute`,并等待返回结果
var result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return TipRoute(
// 路由参数
text: "这个数据是旧页面传递给新页面的",
);
},
),
);
//输出`TipRoute`路由返回结果
print("路由返回值: $result");
},
child: Text("打开提示页"),
),
),
);
}
}
命名路由
有几个要点:
- 注册路由表:要在 MyApp 的 MaterialApp 内,增加如下代码,其中配置
/
的话(也就是首页页面),需要同时配置initialRoute:"/"
initialRoute:"/", //名为"/"的路由作为应用的home(首页)
routes:{
"new_page":(context) => TipRoute(text:'这个参数是配置路由传过来的'),
"/":(context) => RouterTestRoute(), //注册首页路由
},
- 注册路由表后,需要通过配置的路由名称打开页面:
onPressed: () {
Navigator.pushNamed(context, "new_page");
//Navigator.push(context,
// MaterialPageRoute(builder: (context) {
// return NewRoute();
//}));
}
- 可以使用pushNamed传递参数
var result = await Navigator.pushNamed(context, "new_page", arguments: "hi");
,接收参数则是:var args=ModalRoute.of(context)?.settings.arguments;
所有代码
import 'package:flutter/material.dart';
import 'dart:ui';
void main() => runApp(const MyApp());
// void main() => runApp(CupertinoApp(home: CupertinoTestRoute()));
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
initialRoute:"/", //名为"/"的路由作为应用的home(首页)
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
routes:{
"new_page":(context) => TipRoute(text:'这个参数是配置路由传过来的'),
"/":(context) => RouterTestRoute(), //注册首页路由
},
);
}
}
class TipRoute extends StatelessWidget {
TipRoute({
Key? key,
required this.text, // 接收一个text参数
}) : super(key: key);
final String text;
@override
Widget build(BuildContext context) {
//获取路由参数
var args=ModalRoute.of(context)?.settings.arguments;
print('旧页面传递参数的方法2:arguments:$args');
return Scaffold(
appBar: AppBar(
title: Text("提示"),
),
body: Padding(
padding: EdgeInsets.all(18),
child: Center(
child: Column(
children: <Widget>[
Text(text),
ElevatedButton(
onPressed: () => Navigator.pop(context, "这个数据是新页面传递给旧页面的"),
child: Text("返回"),
)
],
),
),
),
);
}
}
class RouterTestRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("初始页面"),
),
body: Center(
child: ElevatedButton(
onPressed: () async {
// 打开`TipRoute`,并等待返回结果
// var result = await Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) {
// return TipRoute(
// // 路由参数
// text: "这个数据是旧页面传递给新页面的",
// );
// },
// ),
// );
var result = await Navigator.pushNamed(context, "new_page", arguments: "hi");
//输出`TipRoute`路由返回结果
print("路由返回值: $result");
},
child: Text("打开提示页"),
),
),
);
}
}
路由生成钩子
MaterialApp有一个onGenerateRoute属性,当调用Navigator.pushNamed(...)打开命名路由时,如果指定的路由名在路由表中已注册,则会调用路由表中的builder函数来生成路由组件;如果路由表中没有注册,才会调用onGenerateRoute来生成路由。有了onGenerateRoute回调,要实现上面控制页面权限的功能就非常容易:我们放弃使用路由表,取而代之的是提供一个onGenerateRoute回调,然后在该回调中进行统一的权限控制,如:
MaterialApp(
... //省略无关代码
onGenerateRoute:(RouteSettings settings){
return MaterialPageRoute(builder: (context){
String routeName = settings.name;
// 如果访问的路由页需要登录,但当前未登录,则直接返回登录页路由,
// 引导用户登录;其他情况则正常打开路由。
}
);
}
);
标签:return,005,Text,学习,context,Navigator,flutter,路由,页面
From: https://www.cnblogs.com/ayubene/p/18289088