Flutter multiple WebView widget error "Bad state: Future already completed"

Issue

My goal is to make a WebView app with several CupertinoTabViews that when clicking each BottomNavigationBarItem, CupertinoTabScaffold shows different WebView containing widgets; pageA and pageB.

As the application launches, the first WebView successfully shows the initial URL webpage.
However, when clicking another Tab button (trying to show another WebView), Unhandled Exception: Bad state: Future already completed is thrown.

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 class)

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

The Unhandled Exception: Bad state: Future already completed error locates the following line:

_controller.complete(webViewController);

Solution

The solution was simple. Move the _controller declaration inside the class.

Answered By – klados

Answer Checked By – Clifford M. (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *