Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to listen to events in flutter webview?

I want to close the webview in my flutter app when the user clicks on a button which is present in the webview

Here is the code which displays the webview

class WebViewApp extends StatefulWidget {
  @override
  _WebViewAppState createState() => _WebViewAppState();
}

class _WebViewAppState extends State<WebViewApp> {
  @override
  Widget build(BuildContext context) {
    return  WebviewScaffold(url: 'https://google.com',
        appBar: AppBar(
          title: Text('Test'),
          centerTitle: true,
          backgroundColor: kBlue,
          leading: BackButton(
            onPressed: (){
              Router.navigator.pop();
            },
          )
        ),
      );
  }
}

example image and i want to detect if the sports

like image 858
Harshvardhan R Avatar asked Aug 01 '20 13:08

Harshvardhan R


People also ask

What is a WebView in flutter?

What Is WebView? If developers want to show any web page or website or load a URL inside an application, a WebView can be displayed without the help of any browser, so, basically, it displays the content of web pages directly inside the application. Let’s get started on how to integrateWebView inside a Flutter application.

How do I create a methodchannel in flutter?

Let start by creating a new Flutter Plugin project and name the project "event_channel_tutorial." Once you have set up a new project, you should have a Dart file generated for you that contains a single MethodChannel. Here is my file, for example: Let's start by defining an Event Channel.

What are event channels in flutter?

The Flutter team covers how to extract information from your native platform using Method Channels. Method Channels are great for requesting data from your native platform when you need it, but what if you want to stream in data from your native platform continuously? That's where Event Channels come in.

How do I create a Flutter App in Android Studio?

Open File → New → New Flutter Project → Flutter Application, and click on Next. Enter the project name, and give the Flutter SDK path on your machine Click on Next. Enter your company domain and package name and click Finish. Android Studio will generate a default application.


1 Answers

Please check the below steps for getting a trigger when the button in a WebView is clicked:

  • Add webview plugin

    webview_flutter: ^3.0.2

  • Added the reference of asset in the pubspec.yaml

     assets:   
        assets/about_us.html
    
  • Added the html file in the assets folder

about_us.html

<html>

<head>
    <script type="text/javascript">
        function invokeNative() {
            MessageInvoker.postMessage('Trigger from Javascript code');
        }
    </script> </head>

<body>
    <form>
        <input type="button" value="Click me!" onclick="invokeNative()" />
    </form> </body>

</html>
  • Added the code for loading WebView.

As per the below statement, you can see I am loading a WebView and when I click on the button named Click me! in WebView the JavascriptChannel in flutter will get invoked with a message "Trigger from Javascript code"

import 'dart:convert';
import 'package:flutter/material.dart'; 
import 'package:flutter/services.dart'; 
import 'package:webview_flutter/webview_flutter.dart';

class WebViewApp extends StatefulWidget {
  WebViewApp({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _WebViewAppState createState() => _WebViewAppState();
}

class _WebViewAppState extends State<WebViewApp> {
  WebViewController _controller;
  Future<void> loadHtmlFromAssets(String filename, controller) async {
    String fileText = await rootBundle.loadString(filename);
    controller.loadUrl(Uri.dataFromString(fileText,
            mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
        .toString());
  }
  Future<String> loadLocal() async {
    return await rootBundle.loadString('assets/about_us.html');
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: FutureBuilder<String>(
        future: loadLocal(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return WebView(
              initialUrl:
                  new Uri.dataFromString(snapshot.data, mimeType: 'text/html')
                      .toString(),
              javascriptMode: JavascriptMode.unrestricted,
              javascriptChannels: <JavascriptChannel>[
                JavascriptChannel(
                    name: 'MessageInvoker',
                    onMessageReceived: (s) {
                    Scaffold.of(context).showSnackBar(SnackBar(
                       content: Text(s.message),
                    ));
                    }),
              ].toSet(),
            );
          } else if (snapshot.hasError) {
            return Text("${snapshot.error}");
          }
          return CircularProgressIndicator();
        },
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

As you can see in the code there is a JavascriptChannel which will get invoked when the user clicks a button in webview. There is a key to identify the channel which in my case was MessageInvoker.

Hopes this will do the trick... enter image description here

like image 192
Rissmon Suresh Avatar answered Nov 09 '22 01:11

Rissmon Suresh