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