получение ошибки в навигации, кстати, экраны во флаттере

#flutter

Вопрос:

Я пытаюсь перемещаться по экранам btw с помощью детектора жестов, но получаю сообщение об ошибке, как это исправить?

Ошибка

= = = = = = = = Исключение, пойманное жестом =============================================================== При обработке жеста было выдано следующее утверждение: Операция навигатора запрашивается с контекстом, который не включает Навигатор.

Контекст, используемый для отправки или отправки маршрутов из Навигатора, должен принадлежать виджету, который является потомком виджета Навигатора. Когда возникло исключение, это был стек: C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/internal/js_dev_runtime/private/ddc_runtime/errors.dart 236:49 бросайте пакеты/флаттер/src/виджеты/навигатор.dart 2732:9 пакетов/флаттер/src/виджеты/навигатор.dart 2738:14 пакетов/task1/main.dart 78:10 [_navigateToNextScreen] пакетов/task1/main.dart 60:21 … Обработчик: «onTap» Распознаватель: TapGestureRecognizer#ae0a6 Отладчик: Определитель жестов состояние: возможно, выигранная арена Конечная позиция: Смещение(857,6, 553,0) Конечная позиция: Смещение(264,6, 206,2) кнопка: 1 отправлено нажатие вниз

Мой код:

    import 'package:flutter/material.dart';
   
   import 'package:url_launcher/url_launcher.dart';
   
   
   void main() {
     runApp(MyApp());
   }
   
   class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
     @override
     Widget build(BuildContext context) {
       return MaterialApp(
         home: Scaffold(
           body: Column(
   
   
             children:  <Widget>[
               Padding(
                 padding: const EdgeInsets.all(18.0),
                 child: Text(
                   'choose an option',
                   style: TextStyle(
                     fontSize: 32,
                     color: Colors.black87,
                   ),
                 ),
               ),
               Center(
                 child: ClipRRect(
                   borderRadius: BorderRadius.all(Radius.circular(45.0)),
                   child: Image(
                     width: 350,
                     image: NetworkImage(
                         'https://images.unsplash.com/photo-1451187580459-43490279c0fa?ixlib=rb-1.2.1amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8amp;auto=formatamp;fit=cropamp;w=872amp;q=80'),
                   ),
                 ),
               ),
   
               SizedBox(
                 height: 40.0,
               ),
               Center(
                 child: ClipRRect(
                   borderRadius: BorderRadius.all(Radius.circular(45.0)),
                   child: GestureDetector(
                     onTap: () {
                       _navigateToNextScreen(context);
                     },
                     child: Image(
                       width: 350,
                       image: NetworkImage(
                           "https://images.unsplash.com/photo-1555967522-37949fc21dcb?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8c2Nob2xhcnxlbnwwfHwwfHw=amp;ixlib=rb-1.2.1amp;auto=formatamp;fit=cropamp;w=500amp;q=60"),
                     ),
                   ),
                 ),
               ),
             ],
           ),
         ),
       );
     }
   
     void _navigateToNextScreen(BuildContext context) {
       Navigator.of(context)
           .push(MaterialPageRoute(builder: (context) => HomePage()));
     }
   }
   
   
   class HomePage extends StatelessWidget {
     void _launchUrl(String _url) async => await launch(_url);
   
     @override
     Widget build(BuildContext context) {
       return Scaffold(
         appBar: AppBar(
           title: Text('Tech News'),
         ),
         body: SingleChildScrollView(
           child: Center(
             child: Column(
               children: <Widget>[
                 SizedBox(
                   height: 40.0,
                 ),
                 ElevatedButton(
                   child: Text('article1'),
                   onPressed: () {
                     _launchUrl(
                         "https://theprint.in/opinion/mark-zuckerberg-and-elon-musks-ai-gamble-shows-why-the-tech-is-not-ready-for-prime-time/744962/");
                   },
                 ),
                 SizedBox(
                   height: 40.0,
                 ),
                 ElevatedButton(
                   child: Text('article2'),
                   onPressed: () {
                     _launchUrl(
                         "https://www.livemint.com/market/stock-market-news/wall-street-slammed-by-rotation-out-of-big-tech-nasdaq-falls-over-2-11633360763474.html");
                   },
                 ),
                 SizedBox(
                   height: 40.0,
                 ),
                 ElevatedButton(
                   child: Text('article3'),
                   onPressed: () {
                     _launchUrl(
                         "https://www.business-standard.com/article/companies/bengaluru-startup-offers-three-day-work-week-to-attract-tech-talent-121100400945_1.html");
                   },
                 ),
                 SizedBox(
                   height: 40.0,
                 ),
                 new InkWell(
                     child: new Text('Open Browser'),
                     onTap: () => launch(
                         'https://docs.flutter.io/flutter/services/UrlLauncher-class.html')),
               ],
             ),
           ),
         ),
       );
     }
   }
   ```
 

Ответ №1:

Что такое Navigator.of(контекст)?

Когда вы звоните Navigator.of(context) , флаттер пытается получить Navigator то, что ему дано context .

Почему вы получаете ошибку?

Navigator помещается в дерево виджетов быть MaterialApp , следовательно, любой context ниже MaterialApp должен быть в состоянии вызвать Navigator.of(context) .

Вы используете context MyApp то, что указано выше MaterialApp , отсюда и ошибка.

Решение

Вам нужно получить контекст, который приведен ниже MaterialApp . Простой способ добиться этого-использовать Builder виджет.

Вот ваш код с использованием Builder , чтобы получить правильный context :

 MaterialApp(
  home: Builder(
    builder: (context) {
      return Scaffold(
        body: Column(
          children:  <Widget>[
            Padding(
              padding: const EdgeInsets.all(18.0),
              child: Text(
                'choose an option',
                style: TextStyle(
                  fontSize: 32,
                  color: Colors.black87,
                ),
              ),
            ),
            Center(
              child: ClipRRect(
                borderRadius: BorderRadius.all(Radius.circular(45.0)),
                child: Image(
                  width: 350,
                  image: NetworkImage(
                      'https://images.unsplash.com/photo-1451187580459-43490279c0fa?ixlib=rb-1.2.1amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8amp;auto=formatamp;fit=cropamp;w=872amp;q=80'),
                ),
              ),
            ),

            SizedBox(
              height: 40.0,
            ),
            Center(
              child: ClipRRect(
                borderRadius: BorderRadius.all(Radius.circular(45.0)),
                child: GestureDetector(
                  onTap: () {
                    _navigateToNextScreen(context);
                  },
                  child: Image(
                    width: 350,
                    image: NetworkImage(
                        "https://images.unsplash.com/photo-1555967522-37949fc21dcb?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8c2Nob2xhcnxlbnwwfHwwfHw=amp;ixlib=rb-1.2.1amp;auto=formatamp;fit=cropamp;w=500amp;q=60"),
                  ),
                ),
              ),
            ),
          ],
        ),
      );
    }
  ),
);