showDialog из корневого виджета - PullRequest
0 голосов
/ 14 ноября 2018

Я хочу показать диалог из корневого виджета (тот, который создал MaterialApp) У меня есть экземпляр NavigatorState, но для showDialog требуется контекст, который будет возвращать Navigator.of(context).

Похоже, мне нужно предоставить контекст из маршрута, но я не могу этого сделать, поскольку у корневого виджета его нет.

РЕДАКТИРОВАТЬ: я нашел обходной путь: Iможет выдать фальшивый маршрут, который существует только для showDialog, а затем выдвинуть этот маршрут после завершения диалога.Не красиво, но работает.

Ответы [ 3 ]

0 голосов
/ 14 ноября 2018

tl; dr: Если вы хотите вызвать showDialog из своего корневого виджета, выдавите свой код в другой виджет (например, StatelessWidget) и вызовите showDialog там.

Во всяком случае, в следующем я собираюсь предположить, что вы столкнулись с этой проблемой:

flutter: No MaterialLocalizations found. 
flutter: MyApp widgets require MaterialLocalizations to be provided by a Localizations widget ancestor. 
flutter: Localizations are used to generate many different messages, labels,and abbreviations which are used by the material library.

Как уже было сказано, showDialog можно вызывать только в BuildContext , у предка которого есть MaterialApp . Следовательно, вы не можете напрямую позвонить showDialog, если у вас есть такая структура:

- MaterialApp
  - Scaffold
    - Button // call show Dialog here

В примере кода это приведет к такому коду: , выбрасывающему ошибку, указанную выше:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(),
      home: Scaffold(
        body: Center(
          child: RaisedButton(
              child: Text('Show dialog!'),
              onPressed: () {
                showDialog(
                    context: context,
                    builder: (BuildContext context) {
                      return Dialog(
                        child: Text('Dialog.'),
                      );
                    });
              }),
        ),
      ),
    );
  }
}

Чтобы устранить эту ошибку, вы можете создать новый Widget, который имеет собственный BuildContext. Модифицированная структура будет выглядеть так:

- MaterialApp
  - Home

- Home     // your own (Stateless)Widget
  - Button // call show Dialog here

Изменение примера кода в приведенной выше структуре приводит к фрагменту кода ниже. showDialog можно назвать без , выдавшим ошибку.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(),
      home: Home()
    );
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton(
            child: Text('Show dialog!'),
            onPressed: () {
              showDialog(
                  context: context,
                  builder: (BuildContext context) {
                    return Dialog(
                      child: Text('Dialog.'),
                    );
                  });
            }),
      ),
    );
  }
}
0 голосов
/ 17 ноября 2018

Я исправил проблему с помощью navigator.overlay.context. Вот пример:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  final navigatorKey = GlobalKey<NavigatorState>();

  void show() {
    final context = navigatorKey.currentState.overlay.context;
    final dialog = AlertDialog(
      content: Text('Test'),
    );
    showDialog(context: context, builder: (x) => dialog);
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      navigatorKey: navigatorKey,
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(),
        body: FlatButton(
          child: Text('Show alert'),
          onPressed: show,
        ),
      ),
    );
  }
}
0 голосов
/ 14 ноября 2018

Поскольку showDialog используется для отображения диалогового окна материала. Оно может использоваться для отображения диалогов только в виджете MaterialApp.Его нельзя использовать для показа диалога за его пределами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...