Ошибка виджета Flutter multiple WebView «Плохое состояние: будущее уже завершено»

#flutter #dart #webview #future #flutter-cupertino

#флаттер #dart #webview #будущее #flutter-купертино

Вопрос:

Моя цель — создать WebView приложение с несколькими CupertinoTabViews , которые при нажатии на каждый из них BottomNavigationBarItem CupertinoTabScaffold отображали бы разные WebView виджеты, содержащие виджеты; pageA и pageB .

При запуске приложения первый WebView успешно отображает исходную веб-страницу URL. Однако при нажатии другой кнопки Tab (попытке отобразить другой WebView) выдается необработанное исключение: плохое состояние: будущее уже завершено.

main.dart

 class _MyHomePageState extends State<MyHomePage> {
  int _currentTabIndex = 0;

  PageWeb pageA;
  PageWeb pageB;

  @override
  void initState() {
    super.initState();

    pageA = new PageWeb(this, ObjectKey(0), "A");
    pageB = new PageWeb(this, ObjectKey(1), "B");
  }

  @override
  Widget build(BuildContext context) {
    final Widget scaffold = CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        currentIndex: _currentTabIndex,
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
              icon: Icon(Icons.home), title: Text('A')),
          BottomNavigationBarItem(
              icon: Icon(Icons.photo), title: Text('B')),
        
        ],
      ),
      tabBuilder: (context, index) {
        CupertinoTabView returnValue;
        switch (index) {
          case 0:
            returnValue = CupertinoTabView(
              builder: (context) {
                return pageA;
              },
            );
            break;
          case 1:
            returnValue = CupertinoTabView(
              builder: (context) {
                return pageB;
              },
            );
            break;
        }
        return returnValue;
      },
    );

    return scaffold;
  }
}
  

pageweb.dart (класс PageWeb)

 final Completer<WebViewController> _controller = Completer<WebViewController>();

class PageWeb extends StatefulWidget {
  final delegate;
  final ObjectKey key;
  final String navTitle;

  PageWeb(this.delegate, this.key, this.navTitle);

  @override
  _PageWebState createState() {
    return _PageWebState();
  }
}

class _PageWebState extends State<PageWeb> {
  bool _isLoading = true;
  final cookieManager = WebviewCookieManager();

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
        navigationBar: CupertinoNavigationBar(
          middle: Text(widget.navTitle),
        ),
        child: SafeArea(
            child: Container(
                child: new WebView(
          key: widget.key,
          initialUrl: "https://www.google.com/search?q=${widget.navTitle}",
          javascriptMode: JavascriptMode.unrestricted,
          onWebViewCreated: (WebViewController webViewController) {
            _controller.complete(webViewController);
            // Here is the error occurring part.
          },
          onPageStarted: (String pageUrl) {
            setState(() {
              _isLoading = true;
            });
          },
          onPageFinished: (String pageUrl) {
            setState(() {
              _isLoading = false;
            });
          },
        ))));
  }
}
  

Необработанное исключение: плохое состояние: будущее уже завершено Ошибка содержит следующую строку:

 _controller.complete(webViewController);
  

Комментарии:

1. Почему ваш контроллер объявлен вне класса?

2. @ChristopherMoore Я буквально «просто» переместил переменную внутри класса и увидел комментарий. Это работает. Спасибо. Мне интересно, почему объявление переменной вне класса вызывает ошибку. Это потому, что объявленная переменная рассматривается как глобальная переменная?

3. Да, это то, что он делает

Ответ №1:

Решение было простым. Переместите _controller объявление внутри класса.

Комментарии:

1. это работает, но в чем проблема объявить этот контроллер вне класса?