From 05def7f5a2f92fe2b651b9ccba37e22e916f5bf8 Mon Sep 17 00:00:00 2001 From: Clinton Volzke Date: Mon, 6 May 2019 20:18:32 +1000 Subject: [PATCH 1/3] Fix back button handler to be compatible with the WillPopScope widget. --- .../WebviewManager.java | 2 +- lib/src/base.dart | 7 ++++++ lib/src/webview_scaffold.dart | 22 ++++++++++++++----- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/android/src/main/java/com/flutter_webview_plugin/WebviewManager.java b/android/src/main/java/com/flutter_webview_plugin/WebviewManager.java index 5256bf39..73604937 100644 --- a/android/src/main/java/com/flutter_webview_plugin/WebviewManager.java +++ b/android/src/main/java/com/flutter_webview_plugin/WebviewManager.java @@ -135,7 +135,7 @@ public boolean onKey(View v, int keyCode, KeyEvent event) { if (webView.canGoBack()) { webView.goBack(); } else { - close(); + FlutterWebviewPlugin.channel.invokeMethod("onBack", null); } return true; } diff --git a/lib/src/base.dart b/lib/src/base.dart index 78cb6b77..1afa1f2c 100644 --- a/lib/src/base.dart +++ b/lib/src/base.dart @@ -23,6 +23,7 @@ class FlutterWebviewPlugin { final _channel = const MethodChannel(_kChannel); + final _onBack = StreamController.broadcast(); final _onDestroy = StreamController.broadcast(); final _onUrlChanged = StreamController.broadcast(); final _onStateChanged = StreamController.broadcast(); @@ -33,6 +34,9 @@ class FlutterWebviewPlugin { Future _handleMessages(MethodCall call) async { switch (call.method) { + case 'onBack': + _onBack.add(null); + break; case 'onDestroy': _onDestroy.add(null); break; @@ -64,6 +68,9 @@ class FlutterWebviewPlugin { /// Listening the OnDestroy LifeCycle Event for Android Stream get onDestroy => _onDestroy.stream; + /// Listening the back key press Event for Android + Stream get onBack => _onBack.stream; + /// Listening url changed Stream get onUrlChanged => _onUrlChanged.stream; diff --git a/lib/src/webview_scaffold.dart b/lib/src/webview_scaffold.dart index 0996ca4e..97ffc424 100644 --- a/lib/src/webview_scaffold.dart +++ b/lib/src/webview_scaffold.dart @@ -69,21 +69,33 @@ class _WebviewScaffoldState extends State { Timer _resizeTimer; StreamSubscription _onStateChanged; - var _onDestroy; + var _onBack; @override void initState() { super.initState(); webviewReference.close(); - _onDestroy = webviewReference.onDestroy.listen((_) { - if (mounted) { + _onBack = webviewReference.onBack.listen((_) { + if (!mounted) return; + + final route = ModalRoute.of(context); + + // Close the native widget only if the back operation was not veto'd + // by the [WillPopScope] widget or similar. + final handler = () => webviewReference.close(); + route?.addScopedWillPopCallback(handler); + try { + // Perform the 'back' operation. Navigator.of(context).pop(); + } finally { + route?.removeScopedWillPopCallback(handler); } }); if (widget.hidden) { - _onStateChanged = webviewReference.onStateChanged.listen((WebViewStateChanged state) { + _onStateChanged = + webviewReference.onStateChanged.listen((WebViewStateChanged state) { if (state.type == WebViewState.finishLoad) { webviewReference.show(); } @@ -94,7 +106,7 @@ class _WebviewScaffoldState extends State { @override void dispose() { super.dispose(); - _onDestroy?.cancel(); + _onBack?.cancel(); _resizeTimer?.cancel(); webviewReference.close(); if (widget.hidden) { From 38e315b79f20ae4c89b0ec0e1ea571c0bb2eddc8 Mon Sep 17 00:00:00 2001 From: Clinton Volzke Date: Tue, 7 May 2019 09:17:54 +1000 Subject: [PATCH 2/3] Fix back button handler to be compatible with the WillPopScope widget. --- lib/src/webview_scaffold.dart | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/lib/src/webview_scaffold.dart b/lib/src/webview_scaffold.dart index 97ffc424..24bbc59a 100644 --- a/lib/src/webview_scaffold.dart +++ b/lib/src/webview_scaffold.dart @@ -76,20 +76,11 @@ class _WebviewScaffoldState extends State { super.initState(); webviewReference.close(); - _onBack = webviewReference.onBack.listen((_) { + _onBack = webviewReference.onBack.listen((_) async { if (!mounted) return; - final route = ModalRoute.of(context); - - // Close the native widget only if the back operation was not veto'd - // by the [WillPopScope] widget or similar. - final handler = () => webviewReference.close(); - route?.addScopedWillPopCallback(handler); - try { - // Perform the 'back' operation. - Navigator.of(context).pop(); - } finally { - route?.removeScopedWillPopCallback(handler); + if (await Navigator.maybePop(context)) { + webviewReference.close(); } }); From 29f5536d581fbbe0aed71fa41afb1949e2422824 Mon Sep 17 00:00:00 2001 From: Clinton Volzke Date: Tue, 7 May 2019 14:45:57 +1000 Subject: [PATCH 3/3] Fix back button handler to be compatible with the WillPopScope widget. --- lib/src/webview_scaffold.dart | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/src/webview_scaffold.dart b/lib/src/webview_scaffold.dart index 24bbc59a..9f610195 100644 --- a/lib/src/webview_scaffold.dart +++ b/lib/src/webview_scaffold.dart @@ -79,8 +79,14 @@ class _WebviewScaffoldState extends State { _onBack = webviewReference.onBack.listen((_) async { if (!mounted) return; - if (await Navigator.maybePop(context)) { + // Equivalent of Navigator.maybePop(), except that [webviewReference] + // is closed when the pop goes ahead. Whether the pop was performed + // can't be determined from the return value of Navigator.maybePop(). + final route = ModalRoute.of(context); + final pop = await route?.willPop(); + if (pop == RoutePopDisposition.pop) { webviewReference.close(); + Navigator.pop(context); } });