disable hit testing if the CompositedTransformFollower is hidden when… (#54981)

* disable hit testing if the CompositedTransformFollower is hidden when there is no leader layer

* update comment
diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart
index 25f8c83..676bfbf 100644
--- a/packages/flutter/lib/src/rendering/proxy_box.dart
+++ b/packages/flutter/lib/src/rendering/proxy_box.dart
@@ -4914,7 +4914,7 @@
   ///
   /// When the render object is not linked, then: if [showWhenUnlinked] is true,
   /// the child is visible and not repositioned; if it is false, then child is
-  /// hidden.
+  /// hidden, and its hit testing is also disabled.
   bool get showWhenUnlinked => _showWhenUnlinked;
   bool _showWhenUnlinked;
   set showWhenUnlinked(bool value) {
@@ -4962,6 +4962,9 @@
 
   @override
   bool hitTest(BoxHitTestResult result, { Offset position }) {
+    // Disables the hit testing if this render object is hidden.
+    if (link.leader == null && !showWhenUnlinked)
+      return false;
     // RenderFollowerLayer objects don't check if they are
     // themselves hit, because it's confusing to think about
     // how the untransformed size and the child's transformed
diff --git a/packages/flutter/test/rendering/proxy_box_test.dart b/packages/flutter/test/rendering/proxy_box_test.dart
index 60dbb5f..6a49841 100644
--- a/packages/flutter/test/rendering/proxy_box_test.dart
+++ b/packages/flutter/test/rendering/proxy_box_test.dart
@@ -493,6 +493,61 @@
     box.translation = const Offset(0.3, 0.3);
     expect(box.markNeedsSemanticsUpdateCallCount, 3);
   });
+
+  test('RenderFollowerLayer hit test without a leader layer and the showWhenUnlinked is true', () {
+    final RenderFollowerLayer follower = RenderFollowerLayer(
+      link: LayerLink(),
+      showWhenUnlinked: true,
+      child: RenderSizedBox(const Size(1.0, 1.0)),
+    );
+    layout(follower, constraints: BoxConstraints.tight(const Size(200.0, 200.0)));
+    final BoxHitTestResult hitTestResult = BoxHitTestResult();
+    expect(follower.hitTest(hitTestResult, position: const Offset(0.0, 0.0)), isTrue);
+  });
+
+  test('RenderFollowerLayer hit test without a leader layer and the showWhenUnlinked is false', () {
+    final RenderFollowerLayer follower = RenderFollowerLayer(
+      link: LayerLink(),
+      showWhenUnlinked: false,
+      child: RenderSizedBox(const Size(1.0, 1.0)),
+    );
+    layout(follower, constraints: BoxConstraints.tight(const Size(200.0, 200.0)));
+    final BoxHitTestResult hitTestResult = BoxHitTestResult();
+    expect(follower.hitTest(hitTestResult, position: const Offset(0.0, 0.0)), isFalse);
+  });
+
+  test('RenderFollowerLayer hit test with a leader layer and the showWhenUnlinked is true', () {
+    // Creates a layer link with a leader.
+    final LayerLink link = LayerLink();
+    final LeaderLayer leader = LeaderLayer(link: link);
+    leader.attach(Object());
+
+    final RenderFollowerLayer follower = RenderFollowerLayer(
+      link: link,
+      showWhenUnlinked: true,
+      child: RenderSizedBox(const Size(1.0, 1.0)),
+    );
+    layout(follower, constraints: BoxConstraints.tight(const Size(200.0, 200.0)));
+    final BoxHitTestResult hitTestResult = BoxHitTestResult();
+    expect(follower.hitTest(hitTestResult, position: const Offset(0.0, 0.0)), isTrue);
+  });
+
+  test('RenderFollowerLayer hit test with a leader layer and the showWhenUnlinked is false', () {
+    // Creates a layer link with a leader.
+    final LayerLink link = LayerLink();
+    final LeaderLayer leader = LeaderLayer(link: link);
+    leader.attach(Object());
+
+    final RenderFollowerLayer follower = RenderFollowerLayer(
+      link: link,
+      showWhenUnlinked: false,
+      child: RenderSizedBox(const Size(1.0, 1.0)),
+    );
+    layout(follower, constraints: BoxConstraints.tight(const Size(200.0, 200.0)));
+    final BoxHitTestResult hitTestResult = BoxHitTestResult();
+    // The follower is still hit testable because there is a leader layer.
+    expect(follower.hitTest(hitTestResult, position: const Offset(0.0, 0.0)), isTrue);
+  });
 }
 
 class _TestRectClipper extends CustomClipper<Rect> {