前言
在使用flutter路由跳转是出现如下错误:
代码:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context){
return new MaterialApp(
title: 'Test Flutter',
home: Scaffold(
body: Center(
child: FlatButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => NewRouter()));
},
child: Text('跳转')),
),
),
);
}
}
class NewRouter extends StatelessWidget {
@override
Widget build (BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("hahahha"),
),
body: Center(
child: Text("new router hahah"),
),
);
}
}
解决方案
把home部分作为一个新的Widget拆出来就可以了。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context){
return new MaterialApp(
title: 'Test Flutter',
home: new MyHomeWidget(),
);
}
}
class MyHomeWidget extends StatelessWidget {
@override
Widget build(BuildContext context){
return new Scaffold(
appBar: AppBar(title: Text('new Flutter'),),
body: new Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text('my first flutter app'),
FlatButton(
color: Colors.green,
child: Text('路由跳转'),
textColor: Colors.white,
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context){
return NewRouter();
})
);
},
)
]
),
),
);
}
}
class NewRouter extends StatelessWidget {
@override
Widget build (BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("hahahha"),
),
body: Center(
child: Text("new router hahah"),
),
);
}
}
为什么我的Navigator操作会出现当前的context找不到Navigator的情况,为什么拆成新的widget就好了?
那下面就来具体分析一下
Navigator
我们经常会在应用中打开许多页面,当我们返回的时候,它会先后退到上一个打开的页面,然后一层一层后退,没错这就是一个堆栈。而在Flutter中,则是由Navigator来负责管理维护这些页面堆栈。
//压一个新的页面到屏幕上
Navigator.of(context).push
//把路由顶层的页面移除
Navigator.of(context).pop
通常我们我们在构建应用的时候并没有手动去创建一个Navigator,也能进行页面导航,这又是为什么呢。
没错,这个Navigator正是MaterialApp为我们提供的。但是如果home,routes,onGenerateRoute和onUnknownRoute都为null,并且builder不为null,MaterialApp则不会创建任何Navigator。
BuildContext
每次我们在编写界面部分代码的时候,都是在build函数中进行操作。而build函数则需要默认传入一个BuildContext。我们来看看这到底是啥
abstract class BuildContext {
/// The current configuration of the [Element] that is this [BuildContext].
Widget get widget;
/// The [BuildOwner] for this context. The [BuildOwner] is in charge of
/// managing the rendering pipeline for this context.
BuildOwner get owner;
...
我们可以看到BuildContext其实是一个抽象类,但是每次build函数传进来的是什么呢。我们来看看构建视图的时候到底发生了什么。