[infra_ui][overlay] Impl hittest and gesture handling interface

This commit is contained in:
Jaylen Bian 2021-07-28 10:07:44 +08:00
parent a231c96aee
commit e7a6a41437
3 changed files with 83 additions and 8 deletions

View File

@ -14,7 +14,7 @@ packages:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.7.0"
version: "2.6.1"
boolean_selector:
dependency: transitive
description:
@ -35,7 +35,7 @@ packages:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
version: "1.2.0"
clock:
dependency: transitive
description:
@ -176,7 +176,7 @@ packages:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
version: "1.3.0"
nested:
dependency: transitive
description:
@ -258,7 +258,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.1"
version: "0.3.0"
textstyle_extensions:
dependency: transitive
description:

View File

@ -0,0 +1,22 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class OverlayHitTestArea extends SingleChildRenderObjectWidget {
const OverlayHitTestArea({
Key? key,
Widget? child,
}) : super(key: key, child: child);
@override
RenderObject createRenderObject(BuildContext context) => RenderOverlayHitTestArea();
}
class RenderOverlayHitTestArea extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
@override
bool hitTest(BoxHitTestResult result, {required Offset position}) {
print('hitTesting');
return super.hitTest(result, position: position);
}
}

View File

@ -1,14 +1,19 @@
import 'package:flutter/material.dart';
import 'overlay_hittest.dart';
final GlobalKey<OverlayManagerState> _key = GlobalKey<OverlayManagerState>();
/// Invoke this method in app generation process
TransitionBuilder overlayManagerBuilder() {
return (context, child) {
return OverlayManager(key: _key, child: child);
}
};
}
class OverlayManager extends StatefulWidget {
const OverlayManager({Key? key, required this.child}) : super(key: key);
final Widget? child;
static OverlayManagerState of(
@ -52,9 +57,57 @@ class OverlayManager extends StatefulWidget {
}
class OverlayManagerState extends State<OverlayManager> {
final Map<String, Map<String, OverlayEntry>> _overlayEntrys = {};
void insert(Widget widget, String featureKey, String key) {
final overlay = Overlay.of(context);
assert(overlay != null);
final entry = OverlayEntry(builder: (_) => widget);
_overlayEntrys[featureKey] ??= {};
_overlayEntrys[featureKey]![key] = entry;
overlay!.insert(entry);
}
void insertAll(List<Widget> widgets, String featureKey, List<String> keys) {
assert(widgets.isNotEmpty);
assert(widgets.length == keys.length);
final overlay = Overlay.of(context);
assert(overlay != null);
List<OverlayEntry> entries = [];
_overlayEntrys[featureKey] ??= {};
for (int idx = 0; idx < widgets.length; idx++) {
final entry = OverlayEntry(builder: (_) => widget);
entries.add(entry);
_overlayEntrys[featureKey]![keys[idx]] = entry;
}
overlay!.insertAll(entries);
}
void remove(String featureKey, String key) {
if (_overlayEntrys.containsKey(featureKey)) {
final entry = _overlayEntrys[featureKey]!.remove(key);
entry?.remove();
}
}
void removeAll(String featureKey) {
if (_overlayEntrys.containsKey(featureKey)) {
final entries = _overlayEntrys.remove(featureKey);
entries?.forEach((_, overlay) {
overlay.remove();
});
}
}
@override
Widget build(BuildContext context) {
Navigator.of(context, rootNavigator: true);
return Container();
assert(widget.child != null);
return GestureDetector(
behavior: HitTestBehavior.translucent,
child: OverlayHitTestArea(child: widget.child),
);
}
}
}