啥?Flutter路由跳转有问题?

75 阅读1分钟

1、Navigator.push 为啥时而可以时而不可以

Navigator.push(context, MaterialPageRoute(builder: (_){  
return ArticlePage();  
}));

image.png

2、原因

  • 以下时错误例子,在22行出错。

因为传的context是第6行的context,是_LoginPgeState的。

  • 它的父级是root——UI根节点。Navigator这个widget的并不是由root创建的,因此在root下一级的上下文中无法获得Navigator
  • 所以问题就在于,Navigator需要通过MaterialApp或者它孩子的上下文。
class _LoginPgeState extends State<LoginPge> {  
final _formKey = GlobalKey<FormState>();  
String? _username, _password;  
final GlobalKey<NavigatorState> navigatorKey = GlobalKey();  
@override  
Widget build(BuildContext context) {  
return MaterialApp(  
navigatorKey: navigatorKey,  
home: Scaffold(  
appBar: AppBar(  
title: Text("登录"),  
),  
body: Form(  
key: _formKey,  
child: ListView(  
padding: EdgeInsets.symmetric(horizontal: 22.0),  
children: <Widget>[  
GestureDetector(  
child: Text("跳转",  
style: TextStyle(color: Colors.red),),  
onTap: (){  
Navigator.push(context, MaterialPageRoute(builder: (_){  
return ArticlePage();  
}));  
},  
),  
_buildUserName(),  
_buildPwd(),  
_buildLogin(),  
_buildRegister(),  
],  
))),  
);  
}

3、解决方案

3.1方案一

  • 让Navigator的context一定是在MaterialApp里面
import 'package:flutter/cupertino.dart';  
import 'package:flutter/material.dart';  
import 'package:wanandroid/ui/page/article_page.dart';  
import 'package:wanandroid/ui/page/page_article.dart';  
  
void main()=> runApp(MyApp3());  
  
class MyApp3 extends StatelessWidget {  
const MyApp3({super.key});  
@override  
Widget build(BuildContext context) {  
return new MaterialApp(  
title: "kentwang",  
home: MainRoute(),  
);  
}  
}  
class MainRoute extends StatelessWidget {  
const MainRoute({super.key});  
@override  
Widget build(BuildContext context) {  
return Scaffold(  
appBar: AppBar(  
title: Text("kentwang"),  
),  
body: Column(  
children: <Widget>[  
Text("first page"),  
ElevatedButton(onPressed: (){  
Navigator.push(context, MaterialPageRoute(builder: (context) {  
return ArticleApp();  
}));  
},  
child: Text("go to next page"),  
)  
],  
),  
);  
}  
}

方案2

  • 和一差不多,用Builder,看19行
Widget _buildRegister(){  
return Padding(  
padding: EdgeInsets.only(top: 10.0),  
child: Row(  
mainAxisAlignment: MainAxisAlignment.center,  
children: <Widget>[  
  
GestureDetector(  
child: Text("没有账号",  
style: TextStyle(color: Colors.red),),  
onTap: (){  
navigatorKey.currentState?.push(MaterialPageRoute(builder: (_){  
return new ArticleApp();  
}));  
},  
  
)  
,  
Builder(builder: (context){  
return GestureDetector(  
child: Text('点击注册',  
style: TextStyle(color: Colors.green),  
),  
onTap: () async{  
Navigator.push(context, MaterialPageRoute(builder: (_){  
return ArticlePage();  
}));  
},  
);  
},)  
],  
),  
);  
  
}

方案3

  • 用navigatorKey,
  • final GlobalKey navigatorKey = GlobalKey();
  • return MaterialApp( navigatorKey: navigatorKey,
  • 在代码处用
    navigatorKey.currentState?.push(MaterialPageRoute(builder: (_){  
        return new ArticleApp();  
    }));