Home > Software engineering >  The following _CastError was thrown building FutureBuilder<WebViewController>
The following _CastError was thrown building FutureBuilder<WebViewController>

Time:09-27

I made program using flutter webview

I have error with _FutureBuilderState<WebViewController

What I want to do make the reload button as FloatingActionButton

I guess this error is relevant with future async function, but I am not sure where to fix.

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following _CastError was thrown building FutureBuilder<WebViewController>(dirty, state:
_FutureBuilderState<WebViewController>#54b59):
Null check operator used on a null value

The relevant error-causing widget was:
  FutureBuilder<WebViewController>
  FutureBuilder:file:///Users/whitebear/MyCode/httproot/guessdrawing_flutter/lib/main.dart:305:12

When the exception was thrown, this was the stack:
#0      NavigationControls.build.<anonymous closure> (package:flutterweb/main.dart:311:59)
#1      _FutureBuilderState.build (package:flutter/src/widgets/async.dart:782:55)
#2      StatefulElement.build (package:flutter/src/widgets/framework.dart:4782:27)
#3      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4665:15)
#4      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4840:11)
#5      Element.rebuild (package:flutter/src/widgets/framework.dart:4355:5)
#6      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4643:5)
#7      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4831:11)
#8      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4638:5)
...     Normal element mounting (29 frames)
#37     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3673:14)
#38     MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6333:36)
#39     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6344:32)
...     Normal element mounting (21 frames)
#60     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3673:14)
#61     MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6333:36)
#62     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6344:32)
...     Normal element mounting (116 frames)
#178    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3673:14)
#179    MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6333:36)
#180    MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6344:32)
...     Normal element mounting (173 frames)
#353    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3673:14)
#354    MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6333:36)
#355    MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6344:32)
...     Normal element mounting (371 frames)
#726    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3673:14)
#727    Element.updateChild (package:flutter/src/widgets/framework.dart:3425:18)
#728    RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1198:16)
#729    RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:1167:5)
#730    RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:1112:18)
#731    BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2573:19)
#732    RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:1111:13)
#733    WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:944:7)
#734    WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:924:7)
(elided 11 frames from class _RawReceivePortImpl, class _Timer, dart:async, and dart:async-patch)

my code is here.

class NavigationControls extends StatelessWidget {
  const NavigationControls(this._webViewControllerFuture)
      : assert(_webViewControllerFuture != null);

  final Future<WebViewController> _webViewControllerFuture;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<WebViewController>(
      future: _webViewControllerFuture,
      builder:
          (BuildContext context, AsyncSnapshot<WebViewController> snapshot) {
        final bool webViewReady =
            snapshot.connectionState == ConnectionState.done;
        final WebViewController controller = snapshot.data!;
        //return IconButton(
        return FloatingActionButton(
              child: const Icon(Icons.replay),
              onPressed: !webViewReady
                ? null
                : () {
                    controller.reload();
                },
        );
      },
    );
  }

NavigationControls is called here.

class WebViewExample extends StatefulWidget {
  @override
  _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  final Completer<WebViewController> _controller =
      Completer<WebViewController>();

  @override
  void initState() {
    super.initState();
    if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(''),iew.
        backgroundColor: Colors.white.withOpacity(0.0),
        elevation: 0.0,
        
      ),
      extendBodyBehindAppBar:true,

      body: Builder(builder: (BuildContext context) {
        return WebView(
          javascriptMode: JavascriptMode.unrestricted,
          onWebViewCreated: (WebViewController webViewController) {
            _controller.complete(webViewController);
            webViewController.loadUrl(
              'https://example.com',
 
            );
          },
          onProgress: (int progress) {
            print("WebView is loading (progress : $progress%)");
          },
          javascriptChannels: <JavascriptChannel>{
            _toasterJavascriptChannel(context),
          },
          navigationDelegate: (NavigationRequest request) {
            if (request.url.startsWith('https://www.youtube.com/')) {
              print('blocking navigation to $request}');
              return NavigationDecision.prevent;
            }
            print('allowing navigation to $request');
            return NavigationDecision.navigate;
          },
          onPageStarted: (String url) {
            print('Page started loading: $url');
          },
          onPageFinished: (String url) {
            print('Page finished loading: $url');
          },
          gestureNavigationEnabled: true,
        );
      }),
      floatingActionButton:NavigationControls(_controller.future),
    );
  }

  JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
    return JavascriptChannel(
        name: 'Toaster',
        onMessageReceived: (JavascriptMessage message) {
          // ignore: deprecated_member_use
          Scaffold.of(context).showSnackBar(
            SnackBar(content: Text(message.message)),
          );
        });
  }
}

CodePudding user response:

The error is exactly at main.dart:305:12. The only null check operator I can see in your code is: final WebViewController controller = snapshot.data!;

So try changing your FAB to something like:

        final bool webViewReady =
            snapshot.connectionState == ConnectionState.done;
        return FloatingActionButton(
              child: const Icon(Icons.replay),
              onPressed: !webViewReady
                ? null
                : () {
                    snapshot.data!.reload();
                },

This way you are not casting the type as non null before its used

  • Related