前言
在现代移动应用开发中,Flutter 作为一个强大的 UI 工具包,提供了简洁高效的方式来构建美观的界面和流畅的用户体验。在 Flutter 中,状态管理和路由管理是构建应用时不可或缺的部分。掌握如何通过 BuildContext 和 GlobalKey 获取状态对象,以及如何有效地管理页面跳转、参数传递和命名路由,能够帮助开发者创建更加灵活和易于维护的应用程序。
获取对象
通过Context获取状态对象
import 'package:flutter/material.dart'; class GetStateObjectRoute extends StatefulWidget{ const GetStateObjectRoute({super.key}); @override State<StatefulWidget> createState() => _GetStateObjectRouteState(); } class _GetStateObjectRouteState extends State<GetStateObjectRoute>{ @override Widget build(BuildContext context) { return MaterialApp( title: "myApp", home: Scaffold( appBar: AppBar( title: const Text('子树中获取的context 对象'), ), body:Center ( child:Column( children: [ Builder(builder: (context){ return ElevatedButton(onPressed: (){ ScaffoldState state= context.findAncestorStateOfType<ScaffoldState>()!; state.openDrawer(); }, child: const Text ('open the menu1')); }), Builder(builder: (context){ return ElevatedButton(onPressed: (){ //通过 of 静态方法 来获取 ScaffoldState ScaffoldState state= Scaffold.of(context); state.openDrawer(); }, child: const Text ('open the menu2')); }), Builder(builder: (context){ return ElevatedButton(onPressed: (){ //通过 of 静态方法 来获取 ScaffoldState ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('i am the SnackBar')) ); }, child: const Text ('show the snackBar')); }) ], ) ), drawer: const Drawer(), ), ); } } main(){ runApp(const GetStateObjectRoute()); }
通过goableKey状态获取
先定义
// 定义一个globalKey 由于globalKey 需要保持全局唯一性,用静态存储 static final GlobalKey<ScaffoldState> _globalKey= GlobalKey();
设置
home: Scaffold( key:_globalKey, //设置key
调用
body:Center ( child: Column( children: [ Builder(builder: (context){ return ElevatedButton(onPressed: (){ // 通过GlobalKey 获取 State 对象 (_globalKey.currentState as ScaffoldState).openDrawer(); }, child: const Text('open Draw1'),); }) ], ),
路由管理
简单使用
ElevatedButton(child:const Text('login',),onPressed: (){ // Navigator.of(context).pushNamed( "successful"); Navigator.push(context, MaterialPageRoute(builder: (context){ return Successful(); })); },),
先定义好主页面
class HomePage extends StatelessWidget{ const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('home page'), ), body: Center( child: TextButton( onPressed: () { // 导航 到 新路由 Navigator.push(context, MaterialPageRoute(builder: (context){ return const NewRoute(); })); }, child: const Text('open new route'), ), ), ); } }
再定义一个路由页面
class NewRoute extends StatefulWidget{ const NewRoute({super.key}); @override State<StatefulWidget> createState() =>_NewRoute(); } class _NewRoute extends State<NewRoute> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title:const Text('this is new Route') , ), body: const Center( child: Text("this is new route"), ), ); } }
启动
跳转 回来
body: Center( child:Column( children: [ Text(" i am news page"), // 获取 newspage 定义 的 title FloatingActionButton(onPressed: (){ Navigator.pop(context); // 返回 到 上一页 },child: Icon(Icons.arrow_back_ios),) ], ) ),
路由传值
使用Navigator
ElevatedButton(onPressed: (){ Navigator.pop(context,'i am the back element'); }, child: const Text('back up')),
使用 result 得到
var result= await Navigator.push(context, MaterialPageRoute(builder: (context){ // text 也可以接受参数 return const TipRoute(text: 'hello'); })); print('router back the result $result');
import 'package:flutter/material.dart'; class RouterTest extends StatelessWidget{ const RouterTest({super.key}); @override Widget build(BuildContext context) { return Center( child: ElevatedButton( onPressed: () async{ // 导航 到 新路由 var result= await Navigator.push(context, MaterialPageRoute(builder: (context){ return const TipRoute(text: 'hello'); })); print('router back the result $result'); }, child: const Text('open the tip page'), ), ); } } class TipRoute extends StatelessWidget{ const TipRoute({Key? key,required this.text}); final String text; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title:const Text('tip') , ), body: Padding( padding: const EdgeInsets.all(18), child: Center( child: Column( children: [ Text(text), ElevatedButton(onPressed: (){ Navigator.pop(context,'i am the back element'); }, child: const Text('back up')), ], ), ), ), ); } } void main(List<String> args){ runApp(const MaterialApp( home:RouterTest())); }
or
SizedBox( child: ElevatedButton( onPressed: () { Navigator.of(context) .push(MaterialPageRoute(builder: (BuildContext context) { return NewsPage( title: "i am news title", ); })); }, child: Text("go to news ")), ),
在 newspage 页面 配置 一个 标题
从 跳转页面 得到 接收
import 'package:flutter/material.dart'; class NewsPage extends StatefulWidget { final String title; const NewsPage({super.key,this.title="news"}); /// 传参 得到 @override State<NewsPage> createState() => _NewsPageState(); } class _NewsPageState extends State<NewsPage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Text(" i am news page"), // 获取 newspage 定义 的 title ), ); } }
命名路由
class NewRoute extends StatelessWidget{ const NewRoute({super.key}); @override Widget build(BuildContext context) { return const Center( child: Text('New route,and the param is ') , ); } }
class HomePage extends StatelessWidget{ const HomePage({super.key}); @override Widget build(BuildContext context) { return Center( child: TextButton( onPressed: (){ // 命名路由 Navigator.of(context).pushNamed('new_page',arguments: ('hello,world')); }, child: const Text('go to the new route'), ), ); } }
void main(List<String>args){ runApp(MaterialApp( title: 'myapp', initialRoute: '/', // 注册表 路由 routes: { 'new_page':(context)=>const NewRoute(), '/':(context)=>const HomePage(), }, )); }
Navigator.of(context).pushNamed( "successful");
SizedBox( child: ElevatedButton( onPressed: () { Navigator.pushNamed(context, "/news"); }, child: Text("命名路由跳转到news")), ),
return MaterialApp( debugShowCheckedModeBanner: false, // home: Tabs(), initialRoute: '/', routes: { "/":(context)=>const Tabs(), "/news":(context)=>const NewsPage(), "/search":(context)=>const SearchPage(), "/form":(context)=>const FormPage(), }, );
返回根路由
如果 有 三次 路由 跳转
使用 pushReplacementNamed 方法 返回 时 可以 跳过 第二个 路由
直接 返回 第一个路由
pushReplacementNamed("/")
:这是一个页面导航方法,它将根据提供的路由名称替换当前的页面。在这种情况下,路由名称为"/"
,表示根页面。通过将当前页面替换为根页面,您可以实现应用程序的重置或返回到初始状态的效果。
总结起来,这段代码的作用是在应用程序中导航到根页面,并替换当前页面。一旦执行了该导航操作,用户将看到根页面,并且无法通过后退按钮返回到之前的页面。
ElevatedButton(onPressed: (){ // Navigator.of(context).pushReplacementNamed("/"); }, child: Text("go back"))
点击图标跳转
创建 路由名字
GestureDetector( onTap: (){ setState(() { Navigator.of(context).pushNamed("/personPage"); }); }, child: Column( children: [ Icon(Icons.home), Text("主页"), ], ), ),