Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 使用不包含导航器的上下文请求的导航器操作_Flutter - Fatal编程技术网

Flutter 使用不包含导航器的上下文请求的导航器操作

Flutter 使用不包含导航器的上下文请求的导航器操作,flutter,Flutter,我试图在onTap中启动新屏幕,但出现以下错误: 请求的导航器操作的上下文不包括 领航员 我用来导航的代码是: onTap: () { Navigator.of(context).pushNamed('/settings'); }, 我已在我的应用程序中设置了一条路线,如下所示: routes: <String, WidgetBuilder>{ '/settings': (BuildContext context) => new SettingsPage(), },

我试图在onTap中启动新屏幕,但出现以下错误:

请求的导航器操作的上下文不包括 领航员

我用来导航的代码是:

onTap: () { Navigator.of(context).pushNamed('/settings'); },
我已在我的应用程序中设置了一条路线,如下所示:

routes: <String, WidgetBuilder>{
    '/settings': (BuildContext context) => new SettingsPage(),
},
class SettingsPage extends Navigator {

Widget buildAppBar(BuildContext context) {
  return new AppBar(
    title: const Text('Settings')
  );
}

@override
Widget build(BuildContext context) {
  return new Scaffold(
    appBar: buildAppBar(context),
  );
 }
}
SettingsPage是一个类,如下所示:

routes: <String, WidgetBuilder>{
    '/settings': (BuildContext context) => new SettingsPage(),
},
class SettingsPage extends Navigator {

Widget buildAppBar(BuildContext context) {
  return new AppBar(
    title: const Text('Settings')
  );
}

@override
Widget build(BuildContext context) {
  return new Scaffold(
    appBar: buildAppBar(context),
  );
 }
}

我在颤振应用程序中设置了一个简单的路由示例:

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      home: new MyHomePage(),
      routes: <String, WidgetBuilder>{
        '/settings': (BuildContext context) => new SettingsPage(),
      },
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('TestProject'),
      ),
      body: new Center(
        child: new FlatButton(
          child: const Text('Go to Settings'),
          onPressed: () => Navigator.of(context).pushNamed('/settings')
        )
      )
    );
  }
}

class SettingsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text('SettingsPage'),
        ),
        body: new Center(
            child: new Text('Settings')
        )
    );
  }
}
导入“包装:颤振/材料.省道”;
void main(){
runApp(新的MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“颤振演示”,
主页:新建MyHomePage(),
路线:{
“/settings”:(BuildContext上下文)=>new SettingsPage(),
},
);
}
}
类MyHomePage扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
归还新脚手架(
appBar:新的appBar(
标题:新文本(“TestProject”),
),
正文:新中心(
孩子:新的扁平按钮(
子项:常量文本(“转到设置”),
onPressed:()=>Navigator.of(context.pushName)(“/settings”)
)
)
);
}
}
类设置SPAGE扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
归还新脚手架(
appBar:新的appBar(
标题:新文本(“设置页面”),
),
正文:新中心(
子项:新文本(“设置”)
)
);
}
}
注意,SettingsPage扩展了无状态小部件,而不是导航器。我无法重现你的错误

此示例是否有助于您构建应用程序?请告诉我是否可以帮助您。

TLDR:将需要访问
Navigator
的小部件包装到
Builder
中,或将该子树提取到类中。并使用新的
BuildContext
访问
Navigator


此错误与目标无关。发生这种情况的原因是您使用了一个不包含
导航器的
上下文
作为父实例

那么如何创建导航器实例呢?

这通常是通过在小部件树中插入
MaterialApp
WidgetApp
来实现的。虽然您可以直接使用
Navigator
手动执行,但不推荐这样做。然后,此类小部件的所有子部件都可以使用
Navigator.of(context)
访问
Navigator.state

等等,我已经有了
MaterialApp
/
WidgetApp

很可能是这样。但是,当您使用
上下文时,仍然可能发生此错误,该上下文是
MaterialApp
/
WidgetApp
的父级

这是因为当您执行(上下文)
Navigator.of时,它将从与所使用的
上下文相关联的小部件开始。然后在小部件树中向上移动,直到找到一个
导航器
,或者不再有小部件

在第一种情况下,一切都很好。在第二种情况下,它抛出一个

使用不包含导航器的上下文请求的导航器操作

那么,如何修复它呢?

首先,让我们重现这个错误:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Center(
        child: RaisedButton(
          child: Text("Foo"),
          onPressed: () => Navigator.pushNamed(context, "/"),
        ),
      ),
    );
  }
}
此示例创建一个按钮,该按钮尝试在单击时转到“/”,但会引发异常

注意这里的

  onPressed: () => Navigator.pushNamed(context, "/"),
我们使用传递给
MyApp
build
context

问题是,
MyApp
实际上是
MaterialApp
的父级。因为是小部件实例化了
MaterialApp
!因此
MyApp
BuildContext
没有
MaterialApp
作为父级

为了解决这个问题,我们需要使用不同的
上下文

在这种情况下,最简单的解决方案是引入一个新的小部件作为
MaterialApp
的子部件。然后使用该小部件的上下文执行
Navigator
调用

有几种方法可以实现这一点。您可以将
home
提取到自定义类中:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHome()
    );
  }
}

class MyHome extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: RaisedButton(
          child: Text("Foo"),
          onPressed: () => Navigator.pushNamed(context, "/"),
        ),
      );
  }
}
或者您可以使用
Builder

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Builder(
        builder: (context) => Center(
              child: RaisedButton(
                child: Text("Foo"),
                onPressed: () => Navigator.pushNamed(context, "/"),
              ),
            ),
      ),
    );
  }
}

完整且经过测试的解决方案:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:my-app/view/main-view.dart';

class SplashView extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        home: Builder(
          builder: (context) => new _SplashContent(),
        ),
        routes: <String, WidgetBuilder>{
          '/main': (BuildContext context) => new MainView()}
    );
  }
}

class _SplashContent extends StatefulWidget{

  @override
  _SplashContentState createState() => new _SplashContentState();
}

class _SplashContentState extends State<_SplashContent>
    with SingleTickerProviderStateMixin {

  var _iconAnimationController;
  var _iconAnimation;

  startTimeout() async {
    var duration = const Duration(seconds: 3);
    return new Timer(duration, handleTimeout);
  }

  void handleTimeout() {
    Navigator.pushReplacementNamed(context, "/main");
  }

  @override
  void initState() {
    super.initState();

    _iconAnimationController = new AnimationController(
        vsync: this, duration: new Duration(milliseconds: 2000));

    _iconAnimation = new CurvedAnimation(
        parent: _iconAnimationController, curve: Curves.easeIn);
    _iconAnimation.addListener(() => this.setState(() {}));

    _iconAnimationController.forward();

    startTimeout();
  }

  @override
  Widget build(BuildContext context) {
    return new Center(
        child: new Image(
          image: new AssetImage("images/logo.png"),
          width: _iconAnimation.value * 100,
          height: _iconAnimation.value * 100,
        )
    );
  }
}
导入'dart:async';
进口“包装:颤振/材料.省道”;
导入“package:my app/view/main view.dart”;
类SplashView扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
住家:建筑商(
生成器:(上下文)=>新建内容(),
),
路线:{
“/main”:(BuildContext上下文)=>new MainView()}
);
}
}
类\u SplashContent扩展StatefulWidget{
@凌驾
_SplashContentState createState()=>new_SplashContentState();
}
类_SplashContentState扩展了状态
使用SingleTickerProviderStateMixin{
var_Iconanimation控制器;
var_iconAnimation;
startTimeout()异步{
变量持续时间=常数持续时间(秒:3);
返回新计时器(持续时间、handleTimeout);
}
void handleTimeout(){
Navigator.pushReplacementNamed(context,“/main”);
}
@凌驾
void initState(){
super.initState();
_iconAnimationController=新的AnimationController(
vsync:this,duration:newduration(毫秒:2000));
_iconAnimation=新曲线动画(
父对象:_iconAnimationController,曲线:Curves.easeIn);
_iconAnimation.addListener(()=>this.setState((){}));
_iconAnimationController.forward();
startTimeout();
}
@凌驾
小部件构建(构建上下文){
返回新中心(
孩子:新形象(
图像:新资产图像(“images/logo.png”),
宽度:_iconAnimation.value*100,
高度:_iconAnimation.value*100,
)
);
}
}

Hy伙计们,我也有同样的问题。这对我来说是不可能的。我找到的解决办法很简单。我所做的只是一个简单的代码:

void main() {
  runApp(MaterialApp(
    home: YOURAPP() ,
    ),
  );
}
我希望是有用的。

M
void main() => runApp(MaterialApp(
      title: "App",
      home: HomeScreen(),
    ));

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text('Title'),
      ),
      body: Center(
          child: Padding(
        padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
        child: RaisedButton(
            onPressed: () {
            //right way: use context in below level tree with MaterialApp
              Navigator.push(context,
                  MaterialPageRoute(builder: (context) => ScanScreen()));
            },
            child: const Text('SCAN')),
      )),
    );
  }
}
final _navKey = GlobalKey<NavigatorState>();

void _navigateToLogin() {
  _navKey.currentState.popUntil((r) => r.isFirst);
  _navKey.currentState.pushReplacementNamed(LoginRoute.name);
}

@override
Widget build(BuildContext context) {
  return MaterialApp(
    navigatorKey: _navKey,
    ...
  );
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Title"),
        ),
        body: new Center(child: new Text("Click Me")),
        floatingActionButton: new FloatingActionButton(
          child: new Icon(Icons.add),
          backgroundColor: Colors.orange,
          onPressed: () {
            print("Clicked");
            Navigator.push(
              context,
              new MaterialPageRoute(builder: (context) => new AddTaskScreen()),
            );
          },
        ),
      ),
    );
  }
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        home: new HomeScreen());
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Title"),
      ),
      body: new Center(child: new Text("Click Me")),
      floatingActionButton: new FloatingActionButton(
        child: new Icon(Icons.add),
        backgroundColor: Colors.orange,
        onPressed: () {
          print("Clicked");
          Navigator.push(
            context,
            new MaterialPageRoute(builder: (context) => new AddTaskScreen()),
          );
        },
      ),
    );
  }
}
builder: (context) => Center(
              child: RaisedButton(
                child: Text("Foo"),
                onPressed: () => Navigator.pushNamed(context, "/"),
              ),
void main() => runApp(MyApp());
void main() {
  runApp(MaterialApp(
  title: 'Your title',
  home: MyApp(),));}
MaterialApp(
      navigatorKey: Get.key,
      initialRoute: "/",
     );
`void main() {
  runApp(MaterialApp(
  title: 'Your title',
  home: MyApp(),));}`