Repository: flutter
Issue: [webview_flutter][iOS] didChangeMetrics() triggers on overlaying widgets
Labels: platform-ios,a: platform-views,p: webview,package,has reproducible steps,P2,found in release: 2.2,team-ios,triaged-ios

### Minimal reproducible example

<details>
<summary>code</summary>
<p>

```dart
import 'dart:io';

import 'package:flutter/material.dart';

import 'package:webview_flutter/webview_flutter.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter WebView Issue Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter WebView Issue Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver{
  bool _showWebView;

  @override
  void initState() {
    if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
    _showWebView = true;
    WidgetsBinding.instance.addObserver(this);
    super.initState();
  }

  @override void didChangeMetrics() {
    print("didChangeMetrics event fired in HomePageState");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Stack(
        children: <Widget>[
          Positioned.fill(
            top: 0,
            left: 0,
            child: Container(
              color: Color.fromARGB(255, 0, 255, 0),
              padding: EdgeInsets.all(100),
              child: (_showWebView) ? WebView(
                initialUrl: 'https://google.com',
                javascriptMode: JavascriptMode.unrestricted,
              )
              :
              Container(
                color: Colors.white,
                child: Center(
                  child: Text(
                    'Container or other widgets as child\ninstead of webview',
                    style: TextStyle(
                      fontSize: 20,
                      color: Colors.black,
                    ),
                    textAlign: TextAlign.center,
                  ),
                ),
              ),
            ),
          ),
          MyFloatingWidget(),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
           _showWebView = !_showWebView;
          });
        },
        child: Icon(Icons.refresh),
        backgroundColor: Colors.green,
      ),
    );
  }
}

class MyFloatingWidget extends StatefulWidget {
  const MyFloatingWidget({Key key}) : super(key: key);

  @override
  MyFloatingWidgetState createState() => MyFloatingWidgetState();
}

class MyFloatingWidgetState extends State<MyFloatingWidget> with WidgetsBindingObserver{

  List<int> _previousTopAndLeft;
  List<int> _requestedTopLeft;
  Offset _dragStartFingerOffset;

  int _didChangeMatricsEventCount;

  @override
  void initState() {
    _previousTopAndLeft = [200, 200];
    _requestedTopLeft = [200, 200];
    _didChangeMatricsEventCount = 0;
    WidgetsBinding.instance.addObserver(this);
    super.initState();
  }

  @override void didChangeMetrics() {
    setState(() {
      _didChangeMatricsEventCount++;
    });
    print("didChangeMetrics event fired in FloatingWidgetState");
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      left: _requestedTopLeft[0].toDouble(),
      top: _requestedTopLeft[1].toDouble(),
      child: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onPanStart: (details) {
          _dragStartFingerOffset = details.globalPosition;
        },        
        onPanUpdate: (details) {
          List<int> _newTopLeft = [_previousTopAndLeft[0] + (details.globalPosition.dx.floor() - _dragStartFingerOffset.dx.floor()), _previousTopAndLeft[1] + (details.globalPosition.dy.floor() - _dragStartFingerOffset.dy.floor())];
          //Some other code to maintain the floating widget within visible area
          setState(() {
            _requestedTopLeft = _newTopLeft;
          });
        },
        onPanEnd: (details) {
          _previousTopAndLeft = _requestedTopLeft;
        },
        child: Container(
          width: 100,
          height: 100,
          decoration: BoxDecoration(
            color: Color.fromARGB(255, 255, 100, 100),
            border: Border.all(color: Color.fromARGB(255, 130, 130, 140)),
            borderRadius: BorderRadius.all(Radius.circular(10)),
            boxShadow: [
              BoxShadow(
                color: Color.fromARGB(255, 200, 200, 210),
                spreadRadius: 3,
                blurRadius: 8,
                offset: Offset(0, 0),
              ),
            ],
          ),
          child: Center(
            child: Text(
              'Matrix Changed :\n' + _didChangeMatricsEventCount.toString(),
              style: TextStyle(
                fontSize: 16,
                color: Colors.black,
              ),
              textAlign: TextAlign.center,
            ),
          ),
        ),
      ),
    );
  }
}
```
</p>
</details>

<details>
<summary>flutter doctor</summary>
<p>

```
[✓] Flutter (Channel stable, 2.0.4, on macOS 11.2.3 20D91 darwin-x64, locale en-IN)
    • Flutter version 2.0.4 at /Users/ambatech/Documents/flutter
    • Framework revision b1395592de (9 weeks ago), 2021-04-01 14:25:01 -0700
    • Engine revision 2dce47073a
    • Dart version 2.12.2

[!] Android toolchain - develop for Android devices (Android SDK version 30.0.0)
    • Android SDK at /Users/ambatech/Library/Android/sdk
    • Platform android-30, build-tools 30.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
    ! Some Android licenses not accepted.  To resolve this, run: flutter doctor --android-licenses

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.4, Build version 12D4e
    • CocoaPods version 1.10.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.0)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 49.0.2
    • Dart plugin version 193.7547
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)

[✓] VS Code (version 1.56.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.23.0

[✓] Connected device (2 available)
    • iPad Pro (9.7-inch) (mobile) • 96ADC6A6-0DF9-4B35-A3B9-D4657C8346A5 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-1 (simulator)
    • Chrome (web)                 • chrome                               • web-javascript • Google Chrome 91.0.4472.77
```
</p>
</details>

### Issue

- Dragging the overlying widget to green area unnecessarily fires `didChangeMetrics()` event in both FloatingWidget and UnderlyingWidget.
- Happening only in **iOS** and when widget is **overlaid on the webview**.
- Behaviour is normal when it is overlaid on any other widgets.
- `didChangeMetrics()` event fires only when it is partially over webview.
- When the widget is fully in green area or fully in webview then event not firing

### Expected behaviour

- While dragging the overlaying widget `didChangeMetrics()` should not unnecessarily fire in FloatingWidget as well as UnderlyingWidget.

This whole thing works fine in Android.


### Similar issues ?
#50420
#58659
#53490

https://user-images.githubusercontent.com/60609139/120477970-fae3ad80-c3c9-11eb-9420-50df3c355dfe.mov