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

ih99xse1  于 2022-12-31  发布在  Android
关注(0)|答案(2)|浏览(137)

我是Flutter的新手,我正在尝试构建一个应用程序。它将有多个页面。当我试图导航到第二个屏幕时,它给了我例外。我看了许多关于如何导航到不同页面的视频,并在我的代码中做了同样的事情,但这给了我期望。
有人能帮我吗?如何解决这个异常?为什么这个异常会出现?
主.dart文件

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

class MyApp extends StatefulWidget {
  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp>{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
        home: Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Text(
                  'Please select your language',
                  style: TextStyle(
                    fontSize:  25,
                    fontWeight: FontWeight.bold
                  ),
                ),

                const Text (
                  'You can change the language at any time',
                  style: TextStyle(
                    fontSize: 16,
                    color: Color.fromRGBO(106, 108, 123, 100)
                  ),
                ),

                DropdownButton<String>(
                  items: <String>['English', 'Hindi', 'Marathi', 'Punjabi'].map((String value) {
                    return DropdownMenuItem<String>(
                      value: value,
                      child: Text(value),
                    );
                  }).toList(),
                  onChanged: (_) {},
                  value: 'English',
                ),

                ElevatedButton(
                    onPressed: (){
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => MobileNumber()//Exception on this line.

                          )
                      );
                    },
                    child: const Text("NEXT"),
                )
              ],
            ),
          )
        )
    );
  }
}

MobileNumber.dart

import 'package:flutter/material.dart';

class MobileNumber extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        body: Text("Mobile Number Page"),
      ),
    );
  }

}

异常堆栈

======== Exception caught by gesture ===============================================================
The following assertion was thrown while handling a gesture:
Navigator operation requested with a context that does not include a Navigator.

The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.
When the exception was thrown, this was the stack: 
#0      Navigator.of.<anonymous closure> (package:flutter/src/widgets/navigator.dart:2554:9)
#1      Navigator.of (package:flutter/src/widgets/navigator.dart:2561:6)
#2      Navigator.push (package:flutter/src/widgets/navigator.dart:2019:22)
#3      MyAppState.build.<anonymous closure> (package:liveasy_task_flutter/main.dart:52:33)
#4      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1072:21)
#5      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:253:24)
#6      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:627:11)
#7      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:306:5)
#8      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:239:7)
#9      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:615:9)
#10     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
#11     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
#12     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
#13     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
#14     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
#15     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:460:19)
#16     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:440:22)
#17     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:337:11)
#18     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:395:7)
#19     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:357:5)
#20     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:314:7)
#21     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:295:7)
#22     _invoke1 (dart:ui/hooks.dart:167:13)
#23     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:341:7)
#24     _dispatchPointerDataPacket (dart:ui/hooks.dart:94:31)
Handler: "onTap"
Recognizer: TapGestureRecognizer#1dfff
  debugOwner: GestureDetector
  state: possible
  won arena
  finalPosition: Offset(183.0, 459.8)
  finalLocalPosition: Offset(32.0, 18.0)
  button: 1
  sent tap down
9o685dep

9o685dep1#

在你的代码中,MaterialApp在内部使用了一个Navigator小部件,这很好。但问题是你使用的context是在它上面定义的。这意味着那个上下文没有Navigator。一个简单的解决方案可能对初学者来说并不直观,那就是把MaterialApp移到小部件之外,如下所示:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatefulWidget {
  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp>{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const Text(
                    'Please select your language',
                    style: TextStyle(
                        fontSize:  25,
                        fontWeight: FontWeight.bold
                    ),
                  ),

                  const Text (
                    'You can change the language at any time',
                    style: TextStyle(
                        fontSize: 16,
                        color: Color.fromRGBO(106, 108, 123, 100)
                    ),
                  ),

                  DropdownButton<String>(
                    items: <String>['English', 'Hindi', 'Marathi', 'Punjabi'].map((String value) {
                      return DropdownMenuItem<String>(
                        value: value,
                        child: Text(value),
                      );
                    }).toList(),
                    onChanged: (_) {},
                    value: 'English',
                  ),

                  ElevatedButton(
                    onPressed: (){
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => MobileNumber()//Exception on this line.

                          )
                      );
                    },
                    child: const Text("NEXT"),
                  )
                ],
              ),
            )

    );
  }
}

这样,MyAppStatebuild方法中的context确实有一个祖先Navigator小部件。

tmb3ates

tmb3ates2#

把Flutter中的小部件看作一棵树,上下文指向用build函数构建的节点。2在您的例子中,

MainScreen    <------ the context
  --> MaterialApp
   (--> Navigator built within MaterialApp)
      --> Scaffold
        --> body
          --> Center
            --> ElevatedButton

因此,当您使用上下文查找导航器时,您使用的是不在导航器下的主屏幕上下文。
您可以创建一个新的无状态或有状态Widget来包含Center和ElevatedButton,因为它们中的构建函数将指向该级别,或者您可以使用构建器并定义构建器回调(它具有指向构建器的上下文)来返回Center + ElevatedButton。

相关问题