基本路由
实现点击按钮跳转到search页面并且传递参数以及在搜索页面添加返回按钮
//- home 界面
import 'package:flutter/material.dart';
import 'Search.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (BuildContext content) {
return SearchPage("我是跳转传递的参数123123");
}));
},
child: Text("跳转搜索页面"),
style: TextButton.styleFrom(
textStyle: TextStyle(fontSize: 20),
backgroundColor: Colors.amber),
)
]);
}
}
//- search 界面
import 'package:flutter/material.dart';
class SearchPage extends StatelessWidget {
String text;
SearchPage(this.text);
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
child: Text("返回"),
onPressed: () {
Navigator.of(context).pop();
},
),
appBar: AppBar(title: Text("搜索页面")),
body: Text(this.text));
}
}
命名路由
注意事项:
如果发现以上错误,是因为子页面使用了
MaterialApp
进行包裹,在根页面进行跳转到其他页面时候也使用了命名路由,在使用Navigator
命名路由时候,子页面不能用MaterialApp
进行包裹;
命名路由跳转案例代码:
main.dart
import 'package:flutter/material.dart';
import 'pages/tabs.dart';
import 'pages/classfiy.dart';
import 'pages/Search.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: Tabs(), routes: {
'/classfiy': (context) => Classify(),
'/search': (context) => SearchPage(),
});
}
}
search页面
import 'package:flutter/material.dart';
class SearchPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
child: Text("返回"),
onPressed: () {
Navigator.of(context).pop();
},
),
appBar: AppBar(title: Text("搜索页面")),
body: Text("搜索页面"),
);
}
}
Classify页面
import 'package:flutter/material.dart';
class Classify extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Text("分类页面"),
);
}
}
tabs 页面
//- 为了案例完整性,将代码放到这里,这个和路由无关
import 'package:flutter/material.dart';
import 'home.dart';
import 'classfiy.dart';
import 'setting.dart';
class Tabs extends StatefulWidget {
Tabs({Key? key}) : super(key: key);
@override
_TabsState createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
int _currentIndex = 0;
List pageList = [
HomePage(),
Classify(),
Setting(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Hello Demo")),
body: pageList[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (int index) {
setState(() {
this._currentIndex = index;
});
},
fixedColor: Colors.green,
// type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(label: "首页", icon: Icon(Icons.home)),
BottomNavigationBarItem(label: "分类", icon: Icon(Icons.category)),
BottomNavigationBarItem(label: "设置", icon: Icon(Icons.settings)),
],
));
}
}
命名路由跳转传递参数案例代码:
第一种传递方法:
- 首先,定义需要传递给新路由的参数
//- 定义了一个utils.js 文件来存放需要传递的路由参数
class nameBean {
String name;
int age;
nameBean(this.name, this.age);
}
- search 页面提取参数
import 'package:flutter/material.dart';
import 'utilts.dart';
class SearchPage extends StatelessWidget {
String title; //- 这个是构造函数传递的参数
SearchPage(this.title);
@override
Widget build(BuildContext context) {
//- 这个是utils定义好的路由参数进行提取
final nameObj = ModalRoute.of(context)!.settings.arguments as nameBean;
return Scaffold(
floatingActionButton: FloatingActionButton(
child: Text("返回"),
onPressed: () {
Navigator.of(context).pop();
},
),
appBar: AppBar(title: Text("${this.title}")),
body: Text("${nameObj.name}---${nameObj.age}"), //- 直接获取需要的参数即可
);
}
}
- home页面创建按钮进行页面跳转并且传递参数
import 'package:flutter/material.dart';
import 'utilts.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(children: <Widget>[
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/search',
arguments: nameBean("李四", 20));
},
child: Text("跳转搜索页面"),
)
]);
}
}
- main.dart 文件进行命名路由定义
import 'package:flutter/material.dart';
import 'pages/tabs.dart';
import 'pages/Search.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Tabs(),
routes: {
'/search': (context, {arguments}) => SearchPage("hello123"),
});
}
}
第二种传递方法:
使用onGenerateRoute提取参数
- 首先,定义需要传递给新路由的参数
//- 定义了一个utils.js 文件来存放需要传递的路由参数
class nameBean {
String name;
int age;
nameBean(this.name, this.age);
}
- search 页面提取参数
import 'package:flutter/material.dart';
import 'utilts.dart';
class SearchPage extends StatelessWidget {
static const routeName = '/search';
String name;
int age;
String title;
SearchPage({
Key? key,
required this.name,
required this.age,
required this.title,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
child: Text("返回"),
onPressed: () {
Navigator.of(context).pop();
},
),
appBar: AppBar(title: Text("${this.title}")),
body: Text("${this.name}---${this.age}"),
);
}
}
- home页面创建按钮进行页面跳转并且传递参数
import 'package:flutter/material.dart';
import 'utilts.dart';
import 'Search.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(children: <Widget>[
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/search',
arguments: nameBean('张三', 20));
},
child: Text("跳转搜索页面"),
),
]);
}
}
- 使用 onGenerateRoute 提取参数
import 'package:flutter/material.dart';
import 'pages/tabs.dart';
import 'pages/Search.dart';
import 'pages/utilts.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Tabs(),
onGenerateRoute: (settings) {
if (settings.name == SearchPage.routeName) {
final args = settings.arguments as nameBean;
return MaterialPageRoute(
builder: (context) {
return SearchPage(name: args.name, age: args.age,title: "我是123");
},
);
}
assert(false, 'Need to implement ${settings.name}');
return null;
});
}
}
路由返回上一级页面
Navigator.of(context).pop();
Navigator.of(context).pushReplacementNamed('/registerSecond') 与 Navigator.pushNamed(context, '/r2') 的区别
pushReplacementNamed 比如我们从用户中心页面跳转到了 registerFirst 页面,然后从 registerFirst 页面通过 pushReplacementNamed 跳转到了 registerSecond 页面。这个时候当我们点击 registerSecond 的返回按钮 .pop() 的时候它会直接返回到用户中心
pushNamed 则返回 .pop() 是上一级页面 registerFirst 页面;如果想返回根目录使用Navigator.of(context).pushAndRemoveUntil( new MaterialPageRoute(builder: (context) => new Tabs(index:1)), (route) => route == null );