Shamar Gray
Shamar Gray

Reputation: 51

How can I make the back button close flutter WebView plugin app on android

I am new to flutter learning on the go, I am trying to make my app close with the back button when there is no more WebView back history. For example in the WebView app the initial URL is google.com and I navigate to yahoo.com, when I press the back button it goes back to google.com and if I press again the app does nothing I want it to exit when no more history. I have tried the CanGoBack() function on the flutter WebView plugin page but am getting errors in vscode. I don't know how to implement that.

import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:firebase_messaging/firebase_messaging.dart';

class WebviewInFlutter extends StatefulWidget {
  WebviewInFlutter({Key key}) : super(key: key);


  @override
  _WebviewInFlutterState createState() => _WebviewInFlutterState();
}

class _WebviewInFlutterState extends State<WebviewInFlutter> {

  final FirebaseMessaging _messaging = FirebaseMessaging();

  @override
  void initState(){

    super.initState();
    _messaging.getToken().then((token) {
      print(token);
    });

    _messaging.configure(
      onMessage: (Map<String, dynamic> message) async{
        print('on message $message');
      },
      onResume: (Map<String, dynamic> message) async{
        print('on resume $message');
      },
      onLaunch: (Map<String, dynamic> message) async{
        print('on launch $message');
      },
    );
    _messaging.requestNotificationPermissions(
        const IosNotificationSettings(sound: true, badge: true, alert: true));

  }
  final flutterWebviewPlugin = new FlutterWebviewPlugin();




  @override
  Widget build(BuildContext context) {

    return WebviewScaffold(
      url: 'https://google.com',
      hidden: true,
      appCacheEnabled: true,
      withJavascript: true,
      withLocalStorage: true,
      appBar: AppBar(
        actions: <Widget>[
              IconButton(
                icon: Icon(Icons.refresh, color: Color.fromRGBO(255, 255, 255, 1.0),),
                onPressed: () => flutterWebviewPlugin.reload(), // this is reloading the url that was provided to webview, not the current URL.
              )
            ],
          elevation: 1.0,
          centerTitle: true,
          title: Text("Google Mobile")

      ),


    );

  }

}



Upvotes: 2

Views: 14295

Answers (4)

user8787628
user8787628

Reputation:

An easy workaround for this is to add an AppBar to the scaffold. Then your back button functionality will work like it normally does in a flutter AppBar.

@override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: AppBar(
        leading: IconButton(
          icon: Icon(Icons.arrow_back_sharp),
          onPressed: () {
            Navigator.of(context).pop();
          },
        ),
        title: const Text('Properties Near You'),
        backgroundColor: Colors.green[700],
      ),


      body: WebView(
        initialUrl: initialUrl,

        javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (webViewController) => _webViewController = webViewController,
        onPageFinished: (String url) {
          if (url == initialUrl) {
            _redirectToStripe(widget.sessionId);
          }
        },
        navigationDelegate: (NavigationRequest request) {
          print(request);
          print(request.url);
          if (request.url.startsWith('http://localhost:5000/success.html')) {
            Navigator.of(context).pop();
            //Navigator.of(context).pushReplacementNamed('/success');
          } else if (request.url.startsWith('http://mykinderpass/cancel')) {
            Navigator.of(context).pop();
            //Navigator.of(context).pushReplacementNamed('/cancel');
          }
          return NavigationDecision.navigate;
        },
      ),

    );
  }

Upvotes: 0

alyabbasi93
alyabbasi93

Reputation: 41

Working code for InAppwebview Goback

WillPopScope(
    onWillPop: () {
      setState(() {
        webView.goBack();
      });
    },

Upvotes: 3

Lorenzo Pichilli
Lorenzo Pichilli

Reputation: 3429

You can try my plugin flutter_inappbrowser (EDIT: it has been renamed to flutter_inappwebview).

An example is presented below:

import 'dart:async';

import 'package:flutter/material.dart';

import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  runApp(new MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: InAppWebViewPage()
    );
  }
}

class InAppWebViewPage extends StatefulWidget {
  @override
  _InAppWebViewPageState createState() => new _InAppWebViewPageState();
}

class _InAppWebViewPageState extends State<InAppWebViewPage> {
  InAppWebViewController webView;

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
        onWillPop: () async {
          if (webView != null) {
            if (await webView.canGoBack()) {
              // get the webview history
              WebHistory webHistory = await webView.getCopyBackForwardList();
              // if webHistory.currentIndex corresponds to 1 or 0
              if (webHistory.currentIndex <= 1) {
                // then it means that we are on the first page
                // so we can exit
                return true;
              }
              webView.goBack();
              return false;
            }
          }
          return true;
        },
        child: Scaffold(
            appBar: AppBar(
                title: Text("InAppWebView")
            ),
            body: Container(
                child: Column(children: <Widget>[
                  Expanded(
                    child: Container(
                      child: InAppWebView(
                        initialUrl: "https://google.com",
                        initialHeaders: {},
                        initialOptions: InAppWebViewWidgetOptions(
                            inAppWebViewOptions: InAppWebViewOptions(
                              debuggingEnabled: true,
                            )
                        ),
                        onWebViewCreated: (InAppWebViewController controller) {
                          webView = controller;
                        },
                        onLoadStart: (InAppWebViewController controller, String url) {

                        },
                        onLoadStop: (InAppWebViewController controller, String url) {

                        },
                      ),
                    ),
                  ),
                ]))
        )
    );
  }
}

As you can see, it uses WillPopScope widget where onWillPop (https://api.flutter.dev/flutter/widgets/WillPopScope/onWillPop.html) I check if the WebView can go back, otherwise the current route will be popped.

Upvotes: 4

Dhiraj Sharma
Dhiraj Sharma

Reputation: 4859

You can customize your back button in AppBar as

..................................

appBar: AppBar(
leading: new IconButton(
              icon: new Icon(Icons.arrow_back),
              onPressed: () {
                flutterWebviewPlugin.canGoBack().then((value) {
                  if (value) {
                    flutterWebviewPlugin.goBack();
                  } else {
                    Navigator.pop(context);
                  }
                });
              }),
actions: <Widget>[

..................................

This will check if you can go back in WebView or no history is available in stack.

Upvotes: 1

Related Questions