I cannot load a new URL in flutter Webview... I have issues using then
and Future
in flutter Webview
Controller...
In a flutter Webview
, I would like to load the initialUrl
, then programmatically retrieve some information from that web page... All works well so far... But then I want the Webview
to automatically load another webpage... but I am not sure how to use the controller
and the Completer
to do that
Snippet:
WebView(
initialUrl: 'https://flutter.dev',
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
onPageFinished: (String url) async{
if (url == 'https://flutter.dev') {
// *** I retrieve some data, then I want to navigate ***
_controller!.loadUrl('https://google.com'); // *** ERROR HERE ***
}
},
)
I tried using the controller
directly,
_controller!.loadUrl('https://google.com');
it works if I don't use a Completer
and instead I just assign the controller
_controller = webViewController;
but does not seem a recommended option:
I found other examples using a FutureBuilder
, but I am not trying to build anything
Here is the full code, in case useful:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';
void main() {
runApp(
const MaterialApp(
home: WebViewApp(),
),
);
}
class WebViewApp extends StatefulWidget {
const WebViewApp({super.key});
@override
State<WebViewApp> createState() => _WebViewAppState();
}
class _WebViewAppState extends State<WebViewApp> {
final Completer<WebViewController> _controller = Completer<WebViewController>();
@override Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter WebView'),),
body: WebView(
initialUrl: 'https://flutter.dev',
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
onPageFinished: (String url) async{
if (url == 'https://flutter.dev') {
// *** I retrieve some data, then I want to navigate ***
_controller!.loadUrl('https://google.com'); // *** ERROR HERE ***
}
},
),
);
}
}
CodePudding user response:
for the subject of how to use completer in that case!
Replace onPageFinished
callback with the following snippet and read the comments carefully
onPageFinished: (String url) async{
// add the missing '/' at the end of the url since the url string is 'https://flutter.dev/'
// NOT 'https://flutter.dev'
if (url == 'https://flutter.dev/') {
// *** I retrieve some data, then I want to navigate ***
final wvController = await _controller.future;
await wvController.loadUrl('https://google.com');
// ***
// No More ERROR
// HERE ***)
}
},
CodePudding user response:
The best way to do this is to use iterators and controllers. No need to mess with the index. After calling the moveNext() function, the URL in the iterator is updated. You can also open a new URL with the loadUrl() function of the controller.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class SamplePage extends StatefulWidget {
const SamplePage({super.key});
@override
State<SamplePage> createState() => _SamplePageState();
}
class _SamplePageState extends State<SamplePage> {
late WebViewController _webViewController;
Iterable<String> urlStrings = [
'https://www.google.com/',
'https://www.yahoo.com/',
'https://www.bing.com/',
'https://flutter.dev/',
'https://altavista.com/'
];
late Iterator<String> urlIterator;
@override
void initState() {
super.initState();
// init url iterator.
urlIterator = urlStrings.iterator;
urlIterator.moveNext();
// Enable virtual display.
if (Platform.isAndroid) WebView.platform = AndroidWebView();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: WebView(
onWebViewCreated: (controller) => setState(() => _webViewController = controller),
initialUrl: urlIterator.current,
onPageFinished: (url) {
urlIterator.moveNext();
_webViewController.loadUrl(urlIterator.current);
},
),
);
}
}