Handling Flutter Webview Back-Button





In this article, we discuss how to handle back-button operations with Flutter and webview in order to allow users to navigate between pages.

In my previous article, I introduced how to implement Flutter Webview URL Listeners to your flutter applications.

Now, we need to add functionality to navigate through the website with the back button. Currently, instead of going back, our application gets closed. To prevent this, we need to add an operation check to see whether the webview can go back, and if it can, then, we need to load the webview of previous pages.

Step 1

To get a callback when we press the back button, we need to wrap our view inside WillPopScope and create a method inside _WebViewWebPageState to check if webview can go back. If it can, then we perform the back operation. Otherwise, we'll show exit dialog.


Dart

Future<bool> _onBack() async {

bool goBack;

var value = await webView.canGoBack(); // check webview can go back

if (value) {

webView.goBack(); // perform webview back operation

return false;

} else {

await showDialog(

context: context,

builder: (context) => new AlertDialog(

title: new Text('Confirmation ', style: TextStyle(color: Colors.purple)),

// Are you sure?

content: new Text('Do you want exit app ? '),

// Do you want to go back?

actions: <Widget>[

new FlatButton(

onPressed: () {

Navigator.of(context).pop(false);

setState(() {

goBack = false;

});

},

child: new Text('Yes'), // No

),

new FlatButton(

onPressed: () {

Navigator.of(context).pop();

setState(() {

goBack = true;

});

},

child: new Text('No'), // Yes

),

],

),

);

if (goBack) Navigator.pop(context); // If user press Yes pop the page

return goBack;

}

}


Step 2

Create one webview variable inside _WebViewWebPageState and assign its value inside the onWebViewCreated method.

Dart

onWebViewCreated: (InAppWebViewController controller) {

webView = controller;

}

Now, run the application, and it will be responsive to the back button operation. The final code will look like the following screenshot. ( File: ProjectRoot/webviewapp/lib/SecondPage.dart )

import 'package:flutter/material.dart';

import 'package:flutter_inappbrowser/flutter_inappbrowser.dart';

import 'package:webviewapp/SecondPage.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

// This widget is the root of your application.

@override

Widget build(BuildContext context) {

return MaterialApp(

title: 'Flutter Demo',

theme: ThemeData(

primarySwatch: Colors.blue,

),

home: WebViewWebPage(),

);

}

}

class WebViewWebPage extends StatefulWidget {

@override

_WebViewWebPageState createState() => _WebViewWebPageState();

}

class _WebViewWebPageState extends State<WebViewWebPage> {

Future<bool> _onBack() async {

bool goBack;

var value = await webView.canGoBack(); // check webview can go back


if (value) {

webView.goBack(); // perform webview back operation

return false;

} else {

await showDialog(

context: context,

builder: (context) => new AlertDialog(

title: new Text('Confirmation ', style: TextStyle(color: Colors.purple)),

// Are you sure?


content: new Text('Do you want exit app ? '),

// Do you want to go back?

actions: <Widget>[

new FlatButton(

onPressed: () {

Navigator.of(context).pop(false);

setState(() {

goBack = false;

});

},

child: new Text(No), // No

),

new FlatButton(

onPressed: () {

Navigator.of(context).pop();

setState(() {

goBack = true;

});

},

child: new Text(Yes), // Yes

),

],

),

);

if (goBack) Navigator.pop(context); // If user press Yes pop the page

return goBack;

}

}

// URL to load

var URL = "https://google.com.tr";

var LISTENINGURL = "https://www.linkedin.com/in/omeryilmaz86/";

// Webview progress

double progress = 0;

InAppWebViewController webView;

@override

Widget build(BuildContext context) {

return WillPopScope(

onWillPop: _onBack,

child: Scaffold(

appBar: AppBar(

title: Text("Webview App"),

),

body: Container(

child: Column(

children: <Widget>[

(progress != 1.0)

? LinearProgressIndicator(

value: progress,

backgroundColor: Colors.grey[200],

valueColor: AlwaysStoppedAnimation<Color>(Colors.purple))

: null, // Should be removed while showing

Expanded(

child: Container(

child: InAppWebView(

initialUrl: URL,

initialHeaders: {},

initialOptions: {},

onWebViewCreated: (InAppWebViewController controller) {

webView = controller;

},

onLoadStart: (InAppWebViewController controller, String url) {


// Listen Url change108

if(URL == LISTENINGURL){

Navigator.of(context, rootNavigator: true)

.push(MaterialPageRoute(

builder: (context) => new SecondPage()));

}

},

onProgressChanged:

(InAppWebViewController controller, int progress) {

setState(() {

this.progress = progress / 100;

});

},

),

),

)

].where((Object o) => o != null).toList()))),

); //Remove null widgets

}

}

class SecondPage extends StatelessWidget {

@override


Widget build(BuildContext context) {

return Scaffold(

appBar: AppBar(

title: Text("Second Page"),

),

body: Container(

child: Center(

child: Text("Hey,there!"),

),

),

);

}

}