transparent_pointer.dart 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import 'package:flutter/foundation.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/rendering.dart';
  4. void main() {
  5. runApp(MyApp());
  6. }
  7. class MyApp extends StatelessWidget {
  8. @override
  9. Widget build(BuildContext context) => MaterialApp(
  10. home: Stack(
  11. fit: StackFit.expand,
  12. children: [
  13. GestureDetector(
  14. onDoubleTap: () => print("double red"),
  15. child: Container(color: Colors.red),
  16. ),
  17. TransparentPointer(
  18. transparent: true,
  19. child: Stack(
  20. children: [
  21. Positioned(
  22. top: 100,
  23. left: 100,
  24. right: 100,
  25. bottom: 100,
  26. child: GestureDetector(
  27. onTap: () => print("green"),
  28. child: Container(color: Colors.green),
  29. ),
  30. )
  31. ],
  32. ),
  33. ),
  34. ],
  35. ),
  36. );
  37. }
  38. class TransparentPointer extends SingleChildRenderObjectWidget {
  39. const TransparentPointer({
  40. super. key,
  41. this.transparent = true,
  42. super.child,
  43. }) : assert(transparent != null);
  44. final bool transparent;
  45. @override
  46. RenderTransparentPointer createRenderObject(BuildContext context) {
  47. return RenderTransparentPointer(
  48. transparent: transparent,
  49. );
  50. }
  51. @override
  52. void updateRenderObject(BuildContext context, RenderTransparentPointer renderObject) {
  53. renderObject
  54. ..transparent = transparent;
  55. }
  56. @override
  57. void debugFillProperties(DiagnosticPropertiesBuilder properties) {
  58. super.debugFillProperties(properties);
  59. properties.add(DiagnosticsProperty<bool>('transparent', transparent));
  60. }
  61. }
  62. class RenderTransparentPointer extends RenderProxyBox {
  63. RenderTransparentPointer({
  64. RenderBox? child,
  65. bool transparent = true,
  66. }) : _transparent = transparent,
  67. super(child) {
  68. assert(_transparent != null);
  69. }
  70. bool get transparent => _transparent;
  71. bool _transparent;
  72. set transparent(bool value) {
  73. assert(value != null);
  74. if (value == _transparent) return;
  75. _transparent = value;
  76. }
  77. @override
  78. bool hitTest(BoxHitTestResult result, {required Offset position}) {
  79. // forward hits to our child:
  80. final hit = super.hitTest(result, position: position);
  81. // but report to our parent that we are not hit when `transparent` is true:
  82. return !transparent && hit;
  83. }
  84. @override
  85. void debugFillProperties(DiagnosticPropertiesBuilder properties) {
  86. super.debugFillProperties(properties);
  87. properties.add(DiagnosticsProperty<bool>('transparent', transparent));
  88. }
  89. }