簡體   English   中英

Flutter:使用不包含導航器的上下文請求的導航器操作

[英]Flutter : Navigator operation requested with a context that does not include a Navigator

我有一個場景,我根據它將用戶重定向到 HomePage 或 LandingPage 的值檢查 SharePreferences 的值。 我不確定我哪里出錯了? 但我在下面收到此錯誤:我想它沒有正確獲取上下文,我知道如何獲取它嗎?。

未處理的異常:使用不包含導航器的上下文請求導航器操作。 E/flutter (11533):用於從 Navigator 推送或彈出路由的上下文必須是作為 Navigator 小部件后代的小部件的上下文。

這是我的代碼:

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;
}

當您調用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;
}

我已經改變了我的代碼

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'))
          ],
        ),
      ),
    );
  }

發生了什么變化?

使用InitScreenMyApp 中家庭代碼創建一個單獨的小部件

問題是什么?

當我們嘗試使用 Navigator.of(context) 推送 Route 時,flutter 會嘗試在給定上下文的小部件樹中查找 Navigator。 在最初的代碼中,沒有帶有導航器的小部件。 因此,為家庭代碼創建一個單獨的小部件。 MyApp 中的 MaterialApp 小部件將具有 Navigator。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM