From 7bdcc15a20248fc17b5867b215bba0c43e29b2c0 Mon Sep 17 00:00:00 2001 From: Carl Poole Date: Thu, 8 Apr 2021 09:04:07 -0500 Subject: [PATCH] feat(android): ability to add listeners to the Capacitor WebView (#4405) --- .../main/java/com/getcapacitor/Bridge.java | 42 +++++++++++++++++++ .../java/com/getcapacitor/BridgeFragment.java | 7 ++++ .../com/getcapacitor/BridgeWebViewClient.java | 14 +++++++ .../com/getcapacitor/WebViewListener.java | 18 ++++++++ 4 files changed, 81 insertions(+) create mode 100644 android/capacitor/src/main/java/com/getcapacitor/WebViewListener.java diff --git a/android/capacitor/src/main/java/com/getcapacitor/Bridge.java b/android/capacitor/src/main/java/com/getcapacitor/Bridge.java index 28d470e1a4..7617eb639a 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/Bridge.java +++ b/android/capacitor/src/main/java/com/getcapacitor/Bridge.java @@ -120,6 +120,9 @@ public class Bridge { // Any URI that was passed to the app on start private Uri intentUri; + // A list of listeners that trigger when webView events occur + private List webViewListeners = new ArrayList<>(); + /** * Create the Bridge with a reference to the main {@link Activity} for the * app, and a reference to the {@link WebView} our app will use. @@ -1107,12 +1110,37 @@ public void setWebViewClient(BridgeWebViewClient client) { this.webViewClient = client; } + List getWebViewListeners() { + return webViewListeners; + } + + void setWebViewListeners(List webViewListeners) { + this.webViewListeners = webViewListeners; + } + + /** + * Add a listener that the WebViewClient can trigger on certain events. + * @param webViewListener A {@link WebViewListener} to add. + */ + public void addWebViewListener(WebViewListener webViewListener) { + webViewListeners.add(webViewListener); + } + + /** + * Remove a listener that the WebViewClient triggers on certain events. + * @param webViewListener A {@link WebViewListener} to remove. + */ + public void removeWebViewListener(WebViewListener webViewListener) { + webViewListeners.remove(webViewListener); + } + static class Builder { private Bundle instanceState = null; private CapConfig config = null; private List> plugins = new ArrayList<>(); private AppCompatActivity activity; + private final List webViewListeners = new ArrayList<>(); Builder(AppCompatActivity activity) { this.activity = activity; @@ -1146,6 +1174,19 @@ public Builder addPlugins(List> plugins) { return this; } + public Builder addWebViewListener(WebViewListener webViewListener) { + webViewListeners.add(webViewListener); + return this; + } + + public Builder addWebViewListeners(List webViewListeners) { + for (WebViewListener listener : webViewListeners) { + this.addWebViewListener(listener); + } + + return this; + } + public Bridge create() { // Cordova initialization ConfigXmlParser parser = new ConfigXmlParser(); @@ -1168,6 +1209,7 @@ public Bridge create() { // Bridge initialization Bridge bridge = new Bridge(activity, webView, plugins, cordovaInterface, pluginManager, preferences, config); bridge.setCordovaWebView(mockWebView); + bridge.setWebViewListeners(webViewListeners); if (instanceState != null) { bridge.restoreInstanceState(instanceState); diff --git a/android/capacitor/src/main/java/com/getcapacitor/BridgeFragment.java b/android/capacitor/src/main/java/com/getcapacitor/BridgeFragment.java index eadcd39d88..4ee951beed 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/BridgeFragment.java +++ b/android/capacitor/src/main/java/com/getcapacitor/BridgeFragment.java @@ -28,6 +28,8 @@ public class BridgeFragment extends Fragment { private final List> initialPlugins = new ArrayList<>(); private CapConfig config = null; + private final List webViewListeners = new ArrayList<>(); + public BridgeFragment() { // Required empty public constructor } @@ -55,6 +57,10 @@ public void setConfig(CapConfig config) { this.config = config; } + public void addWebViewListener(WebViewListener webViewListener) { + webViewListeners.add(webViewListener); + } + /** * Load the WebView and create the Bridge */ @@ -73,6 +79,7 @@ protected void load(Bundle savedInstanceState) { .setInstanceState(savedInstanceState) .setPlugins(initialPlugins) .setConfig(config) + .addWebViewListeners(webViewListeners) .create(); if (startDir != null) { diff --git a/android/capacitor/src/main/java/com/getcapacitor/BridgeWebViewClient.java b/android/capacitor/src/main/java/com/getcapacitor/BridgeWebViewClient.java index 3a0aa2a597..a2b81a85e8 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/BridgeWebViewClient.java +++ b/android/capacitor/src/main/java/com/getcapacitor/BridgeWebViewClient.java @@ -5,6 +5,7 @@ import android.webkit.WebResourceResponse; import android.webkit.WebView; import android.webkit.WebViewClient; +import java.util.List; public class BridgeWebViewClient extends WebViewClient { @@ -29,4 +30,17 @@ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request public boolean shouldOverrideUrlLoading(WebView view, String url) { return bridge.launchIntent(Uri.parse(url)); } + + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + + List webViewListeners = bridge.getWebViewListeners(); + + if (webViewListeners != null && view.getProgress() == 100) { + for (WebViewListener listener : bridge.getWebViewListeners()) { + listener.onPageLoaded(view); + } + } + } } diff --git a/android/capacitor/src/main/java/com/getcapacitor/WebViewListener.java b/android/capacitor/src/main/java/com/getcapacitor/WebViewListener.java new file mode 100644 index 0000000000..88f42efd04 --- /dev/null +++ b/android/capacitor/src/main/java/com/getcapacitor/WebViewListener.java @@ -0,0 +1,18 @@ +package com.getcapacitor; + +import android.webkit.WebView; + +/** + * Provides callbacks associated with the {@link BridgeWebViewClient} + */ +public abstract class WebViewListener { + + /** + * Callback for page load event. + * + * @param webView The WebView that loaded + */ + public void onPageLoaded(WebView webView) { + // Override me to add behavior to the page loaded event + } +}