WebView can not load two different urls in flutter? - flutter

I print the url message at the first line in build method. And here, the url is right, but the webView has no effect.
I use the webview_flutter lib, and the version is 0.3.13;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() => runApp(WebPage());
class WebPage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _WebPageState();
}
}
class _WebPageState extends State<WebPage> {
String url = "https://flutter.dev/";
void _changeUrl() {
setState(() {
this.url = "https://github.com/flutter/flutter";
});
}
#override
Widget build(BuildContext context) {
print("url:" + url);
return MaterialApp(
theme: ThemeData(primarySwatch: Colors.blue),
home: Scaffold(
appBar: AppBar(
title: Text("WebPage"),
),
body: WebView(
initialUrl: url,
javascriptMode: JavascriptMode.unrestricted,
),
floatingActionButton: FloatingActionButton(
onPressed: _changeUrl,
child: Icon(Icons.replay),
),
));
}
}
I excepted the webView load the second url, but it not.

you need to use web-view controller class methods like this
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() => runApp(WebPage());
class WebPage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _WebPageState();
}
}
class _WebPageState extends State<WebPage> {
WebViewController controller;
var url = "https://flutter.dev/";
changeUrl() {
setState(() {
url = "https://github.com/flutter/flutter";
controller.loadUrl(url);
});
}
#override
Widget build(BuildContext context) {
print("url:" + url);
return MaterialApp(
theme: ThemeData(primarySwatch: Colors.blue),
home: Scaffold(
appBar: AppBar(
title: Text("WebPage"),
),
body: WebView(
// key: _key,
javascriptMode: JavascriptMode.unrestricted,
initialUrl: url,
onWebViewCreated: (WebViewController webViewController) {
controller = webViewController;
}),
floatingActionButton: FloatingActionButton(
onPressed: () {
changeUrl();
},
child: Icon(Icons.replay),
),
));
}
}
more methods to controller could be found here flutter web-view class methods

Related

net::err_unknown_url_scheme phone, whatsapp and telegram link on webview_flutter

I'm new to mobile development and I can't find the answer to this question: I have a website and the website has links to whatsapp, telegram, phone and instagram profile. webview_flutter loads the page but when I click on the links it gives me the error net::err_unknown_url_scheme. The webpage at whatsapp://send/?phone=%2B996500777888.........
enter image description here
main.dart
import 'package:flutter/material.dart';
import 'page/webview_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'НоНси-ОРТ',
theme: ThemeData.dark(),
home: const WebViewPage(),
);
}
}
webview_page.dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebViewPage extends StatefulWidget {
const WebViewPage({super.key});
#override
State<WebViewPage> createState() => _WebViewPageState();
}
class _WebViewPageState extends State<WebViewPage> {
late WebViewController _webController;
double progress = 0;
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
if (await _webController.canGoBack()) {
_webController.goBack();
}
// Stay App
return false;
},
child: Scaffold(
appBar: AppBar(
toolbarHeight: 0,
),
body: Column(
children: [
LinearProgressIndicator(
value: progress,
color: Colors.red,
backgroundColor: Colors.black,
),
Expanded(
child: WebView(
javascriptMode: JavascriptMode.unrestricted,
initialUrl: 'https://ort.nonsi.kg',
onWebViewCreated: (controller) {
_webController = controller;
},
onProgress: (progress) {
this.progress = progress / 100;
setState(() {});
},
),
),
],
),
),
);
}
}
First, add url_launcher library to your project and use navigationDelegate in your webview to handle the link clicks.
WebView(
javascriptMode: JavascriptMode.unrestricted,
initialUrl: 'https://ort.nonsi.kg',
onWebViewCreated: (controller) {
_webController = controller;
},
onProgress: (progress) {
this.progress = progress / 100;
setState(() {});
},
navigationDelegate: (navigationRequest) async {
final link = navigationRequest.url;
final uri = Uri.parse(link);
if(await canLaunchUrl(uri)) {
await launchUrl(uri);
}
return NavigationDecision.prevent;
}
),

How to Create a Progress Indicator for WebView in Flutter

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: WebViewClass()
)
);
}
}
class WebViewClass extends StatefulWidget {
WebViewState createState() => WebViewState();
}
class WebViewState extends State<WebViewClass>{
num position = 1 ;
final key = UniqueKey();
doneLoading(String A) {
setState(() {
position = 0;
});
}
startLoading(String A){
setState(() {
position = 1;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Show ProgressBar While Loading Webview')),
body: IndexedStack(
index: position,
children: <Widget>[
WebView(
initialUrl: 'https://Google.com',
javascriptMode: JavascriptMode.unrestricted,
key: key ,
onPageFinished: doneLoading,
onPageStarted: startLoading,
),
Container(
color: Colors.white,
child: Center(
child: CircularProgressIndicator()),
),
])
);
}
}
Why is this error showing? Basically I want to add progress bar on flutter webview before loading the full website. After many searching I got this code but I also showing error. Is there any problem in this code or if you can, kindly help me with new code.
Follow this,
Replace num with int?, at line no 26 -> like, int? position = 1 ;
Add !(Exclamation mark) after position, at line no 48 -> like, index: position!.
Happy codding!

how to allow mailto schemes in webview flutter

I am working on Flutter webview apps using Flutter Webview plugin.
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:url_launcher/url_launcher.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child : const WebView(
initialUrl: 'https://google.com',
javascriptMode: JavascriptMode.unrestricted,
),
)
)
);
}
}
However, if any links inside the opened web page is an app link, like: fb://profile, I will get net::ERR_UNKNOWN_URL_SCHEME.
In android, I found the solution is to override shouldOverrideUrlLoading as mentioned here, but what should I do in flutter?
I'm trying the solution mentioned here.
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:url_launcher/url_launcher.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child : const WebView(
initialUrl: 'https://google.com',
javascriptMode: JavascriptMode.unrestricted,
navigationDelegate: (NavigationRequest request) {
if (request.url.contains("mailto:")) {
launch(request.url);
return NavigationDecision.navigate;
}
},
),
)
)
);
}
}
But it is throwing errors like
Error: Not a constant expression.
if (request.url.contains("mailto:")) {
You can copy paste run full code below
Step 1: You can remove const keyword from const WebView
Step 2: You can use NavigationDecision.prevent
working demo
full code
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:url_launcher/url_launcher.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: WebView(
initialUrl:
'https://google.com', //'''https://www.scottseverance.us/mailto.html',
javascriptMode: JavascriptMode.unrestricted,
navigationDelegate: (NavigationRequest request) {
print(request.url);
if (request.url.contains("mailto:")) {
launch(request.url);
return NavigationDecision.prevent;
} else {
return NavigationDecision.navigate;
}
},
),
)));
}
}

How can I go back to the previous page with flutter_webview on button click?

I want to build a simple app using webview_flutter with no AppBar, with a static URL, and just a simple floatingActionButton on the bottom of the screen to navigate to the previous page, but I don't know how to do it.
Can someone just give me some guidelines so I can try to make the button do what it is supposed to do?
Here's an image of the app with the button:
I dunno what to try, but I'm trying to learn, sry about that =D
This is my whole code:
=)
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter/services.dart';
import 'dart:async';
void main () {
runApp(MaterialApp(
title: 'Something',
home: AplicativoB2b(),
debugShowCheckedModeBanner: false,
));
SystemChrome.setEnabledSystemUIOverlays ([]);
}
class AplicativoB2b extends StatefulWidget {
#override
_AplicativoB2bState createState() => _AplicativoB2bState();
}
class _AplicativoB2bState extends State<AplicativoB2b> {
Completer<WebViewController> _controller = Completer<WebViewController>();
#override
Widget build(BuildContext context) {
return Scaffold(
body: WebView(
initialUrl: 'https://google.com',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
//HELP ME HERE!! =(
},
child: const Icon(Icons.arrow_back),
backgroundColor: Colors.black,
),
// bottomNavigationBar: BottomAppBar(color: Colors.white, child: Container(height: 50.0),),
// floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
);
}
}
Future<bool> _willPopCallback() async {
WebViewController webViewController = await _controller.future;
bool canNavigate = await webViewController.canGoBack();
if (canNavigate) {
webViewController.goBack();
return false;
} else {
return true;
}
}
I did it with different code than the previous answer. I followed this tutorial to get the webview & the floating button working. From there, it is really easy to give the floating button a back arrow icon and make the webview go back a page when the floating button is clicked.
To make the webview go back a page when the floating button is clicked (put this in its onpressed method):
controller.data.goBack();
The icon of the floating button can easily be changed at this line of code:
child: Icon(Icons.arrow_back)
All of the different buttons can be found here: link
Here is all of my code:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'App'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final Completer<WebViewController> _controller = Completer<WebViewController>();
#override
Widget build(BuildContext context) {
return Scaffold(
body: WebView(
initialUrl: "https://google.com",
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
),
floatingActionButton: FutureBuilder<WebViewController>(
future: _controller.future,
builder: (BuildContext context,
AsyncSnapshot<WebViewController> controller) {
if (controller.hasData) {
return FloatingActionButton(
child: Icon(Icons.arrow_back),
onPressed: () {
controller.data.goBack();
});
}
return Container();
}
),
);
}
}
I did it! =D
It might look simple to lots of people haha, but for someone who never touched this kind of stuff before, I'm very proud of my ninja Ctrl C + Ctrl V. Just kidding, I looked at loads of exemples and tried this and it workd, if anyone has any suggestions I'd aprecciate it! =)
Here's what I did:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter/services.dart';
import 'dart:async';
void main () {
runApp(MaterialApp(
title: 'Something',
home: AplicativoB2b(),
debugShowCheckedModeBanner: false,
));
SystemChrome.setEnabledSystemUIOverlays ([]);
}
class AplicativoB2b extends StatefulWidget {
#override
_AplicativoB2bState createState() => _AplicativoB2bState();
}
class _AplicativoB2bState extends State<AplicativoB2b> {
Completer<WebViewController> _controller = Completer<WebViewController>();
#override
Widget build(BuildContext context) {
return Scaffold(
body: WebView(
initialUrl: 'https://google.com',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
),
floatingActionButton: NavigationControls(_controller.future), // <-- added this
);
}
}
And the class I used for the floatingActionButton.
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 FloatingActionButton.extended(
onPressed: !webViewReady
? null
: () => navigate(context, controller, goBack: true),
icon: Icon(Icons.arrow_back),
backgroundColor: Colors.black,
label: Text("Voltar"),
);
},
);
}
navigate(BuildContext context, WebViewController controller,
{bool goBack: false}) async {
bool canNavigate =
goBack ? await controller.canGoBack() : await controller.canGoForward();
if (canNavigate) {
goBack ? controller.goBack() : controller.goForward();
} else {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text("Sem histórico anterior")),
);
}
}
}
That's basically the whole code. Flutter is cool and easy to lean when you really want it.
Thx to all!

Flutter load webview inside the fragment

// Here is my flutter code
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
class HairtipsPage extends StatefulWidget {
#override
_HairtipsPageState createState() => _HairtipsPageState();
}
class _HairtipsPageState extends State<HairtipsPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child : WebviewScaffold(
url: "https://www.google.com",
appBar: new AppBar(
// title: new Text('Hairtips'),
),
withZoom: true,
withLocalStorage: true,
)
),
);
}
}
I am using bottom navigation in my app and trying to implement webview inside the fragment.i know how to acheive the same in android also i dont want the webview should open in a browser.i am expecting the webview should load inside the app and within the fragment.
You can use the Flutter webview plugin. Here is the URL for the plugin https://pub.dartlang.org/packages/webview_flutter
The webview will load inside the App with CircularProgressIndicator.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebView extends StatefulWidget {
#override
_WebViewState createState() => _WebViewState();
}
class _WebViewState extends State<WebView> {
final Completer<WebViewController> _controller =
Completer<WebViewController>();
num _stackToView = 1;
void _handleLoad(String value) {
setState(() {
_stackToView = 0;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: Builder(builder: (BuildContext context) {
return IconButton(
icon: Icon(Icons.volume_up, color: Colors.black,),
onPressed: () {
Navigator.pop(context);
},
);
}),
backgroundColor: Colors.white10,
elevation: 0,
),
body: IndexedStack(
index: _stackToView,
children: [
Column(
children: <Widget>[
Expanded(
child: WebView(
initialUrl: "https://www.google.co.in/",
javascriptMode: JavascriptMode.unrestricted,
onPageFinished: _handleLoad,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
)),
],
),
Container(
child: Center(child: CircularProgressIndicator(),)
),
],
));
}
}