Browse Source

Fix back button handler to be compatible with the WillPopScope widget.

Clinton Volzke 6 years ago
parent
commit
ebaffcbaf6

+ 1 - 1
android/src/main/java/com/flutter_webview_plugin/WebviewManager.java

@@ -135,7 +135,7 @@ class WebviewManager {
                             if (webView.canGoBack()) {
                                 webView.goBack();
                             } else {
-                                close();
+                                FlutterWebviewPlugin.channel.invokeMethod("onBack", null);
                             }
                             return true;
                     }

+ 7 - 0
lib/src/base.dart

@@ -23,6 +23,7 @@ class FlutterWebviewPlugin {
 
   final _channel = const MethodChannel(_kChannel);
 
+  final _onBack = StreamController<Null>.broadcast();
   final _onDestroy = StreamController<Null>.broadcast();
   final _onUrlChanged = StreamController<String>.broadcast();
   final _onStateChanged = StreamController<WebViewStateChanged>.broadcast();
@@ -33,6 +34,9 @@ class FlutterWebviewPlugin {
 
   Future<Null> _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<Null> get onDestroy => _onDestroy.stream;
 
+  /// Listening the back key press Event for Android
+  Stream<Null> get onBack => _onBack.stream;
+
   /// Listening url changed
   Stream<String> get onUrlChanged => _onUrlChanged.stream;
 

+ 17 - 5
lib/src/webview_scaffold.dart

@@ -69,21 +69,33 @@ class _WebviewScaffoldState extends State<WebviewScaffold> {
   Timer _resizeTimer;
   StreamSubscription<WebViewStateChanged> _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<WebviewScaffold> {
   @override
   void dispose() {
     super.dispose();
-    _onDestroy?.cancel();
+    _onBack?.cancel();
     _resizeTimer?.cancel();
     webviewReference.close();
     if (widget.hidden) {