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

时间:2019-07-28 12:42:52

标签: flutter

我有一个方案,其中我根据该值检查SharePreferences的值,它将用户重定向到HomePage或LandingPage。我不确定我在哪里弄错了?但是我在下面遇到了这个错误:我猜它没有正确的上下文,我不知道该怎么办?。

  

未处理的异常:请求的导航器操作具有不包含导航器的上下文。   E / flutter(11533):用于从Navigator推送或弹出路由的上下文必须是作为Widget的后代的Widget的上下文。

这是我的代码:

import 'package:credit/src/pages/landing.dart';
import 'package:flutter/material.dart';
import 'package:credit/src/pages/credit/home.dart';
import 'package:shared_preferences/shared_preferences.dart';

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

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

  _LoadingPageState createState() => _LoadingPageState();
}

class _LoadingPageState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    getUserStatus().then((userStatus) {
      if (userStatus == null) {
        Navigator.of(context)
            .push(MaterialPageRoute<Null>(builder: (BuildContext context) {
          return LandingPage();
        }));
      } else {
        Navigator.of(context)
            .push(MaterialPageRoute<Null>(builder: (BuildContext context) {
          return HomePage();
        }));
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        child: Center(
      child: CircularProgressIndicator(),
    ));
  }
}

Future<String> getUserStatus() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  String userStatus = prefs.getString('userstatus');
  print("==On Load Check ==");
  print(userStatus);
  return userStatus;
}

2 个答案:

答案 0 :(得分:1)

调用Navigator.of(context)时,框架会出现在提供的context所附加的小部件树中,并试图找到最接近的Navigator

您显示的窗口小部件树没有一个,因此您需要在窗口小部件树中包括Navigator
最简单的选择是将MaterialApp与作为home传递的窗口小部件一起使用。 MaterialApp正在内部创建导航器。 (CupertinoApp也这样做)

原始示例的更新代码:

import 'package:credit/src/pages/landing.dart';
import 'package:flutter/material.dart';
import 'package:credit/src/pages/credit/home.dart';
import 'package:shared_preferences/shared_preferences.dart';

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

class MyApp extends StatelessWidget {
  MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LoadingPage(),
    );
  }
}

class LoadingPage extends StatefulWidget {
  LoadingPage({Key key}) : super(key: key);

  _LoadingPageState createState() => _LoadingPageState();
}

class _LoadingPageState extends State<LoadingPage> { // note type update
  @override
  void initState() {
    super.initState();
    getUserStatus().then((userStatus) {
      if (userStatus == null) {
        Navigator.of(context)
            .push(MaterialPageRoute<Null>(builder: (BuildContext context) {
          return LandingPage();
        }));
      } else {
        Navigator.of(context)
            .push(MaterialPageRoute<Null>(builder: (BuildContext context) {
          return HomePage();
        }));
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        child: Center(
      child: CircularProgressIndicator(),
    ));
  }
}

Future<String> getUserStatus() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  String userStatus = prefs.getString('userstatus');
  print("==On Load Check ==");
  print(userStatus);
  return userStatus;
}

答案 1 :(得分:0)

我已经更改了我的代码

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Demo App',
      theme: ThemeData(
        primarySwatch: white,
        scaffoldBackgroundColor: Colors.white,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Demo App'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                  onPressed: () {
                    Navigator.push(
                        context,
                        MaterialPageRoute(
                            builder: (context) =>
                                HomeScreen(title: 'Demo Home')));
                  },
                  child: Text('Open Home Screen'))
            ],
          ),
        ),
      ),
    );
  }
 

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Demo App',
        theme: ThemeData(
          primarySwatch: white,
          scaffoldBackgroundColor: Colors.white,
        ),
        home: InitScreen());
  }
}

class InitScreen extends StatelessWidget {
  const InitScreen({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Demo App'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
                onPressed: () {
                  Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) =>
                              HomeScreen(title: 'Demo Home')));
                },
                child: Text('Open Home Screen'))
          ],
        ),
      ),
    );
  }

发生了什么变化?

<块引用>

使用 InitScreen

MyApp 中为 home 代码创建一个单独的小部件

出了什么问题?

<块引用>

当我们尝试使用 Navigator.of(context) 推送 Route 时,flutter 会 尝试在给定上下文的小部件树中查找 Navigator。在里面 初始代码,没有带导航器的小部件。所以,创建一个 用于家庭代码的单独小部件。以及 MyApp 中的 MaterialApp 小部件 将有导航器。