Overlayを使ってみる

Overlayを使ってみる

package:in_app_notification
Fleet風エディタ
WidgetsApp で普段操作するUIの手前側にWidgetを表示する仕組み
class _ContentsState extends State<Contents> { OverlayEntry? entry; final random = math.Random(); void tapped() { final percentage = random.nextInt(100); entry?.remove(); entry = OverlayEntry( builder: (context) => Positioned( top: 32, left: MediaQuery.of(context).size.width * percentage / 100, child: Material(child: Text('$percentage')), ), ); Navigator.of(context).overlay?.insert(entry!); } @override Widget build(BuildContext context) { // ボタンをタップして `tapped()` を呼び出すコード } }class _ContentsState extends State<Contents> { OverlayEntry? entry; final random = math.Random(); void tapped() { final percentage = random.nextInt(100); entry?.remove(); entry = OverlayEntry( builder: (context) => Positioned( top: 32, left: MediaQuery.of(context).size.width * percentage / 100, child: Material(child: Text('$percentage')), ), ); Navigator.of(context).overlay?.insert(entry!); } @override Widget build(BuildContext context) { // ボタンをタップして `tapped()` を呼び出すコード } }
class _ContentsState extends State<Contents> { OverlayEntry? entry; Offset mouse = Offset.zero; // ... @override Widget build(BuildContext context) { return MouseRegion( onHover: (event) { setState(() => mouse = event.localPosition); entry?.markNeedsBuild(); }, child: Scaffold( // ... ), ); } }class _ContentsState extends State<Contents> { OverlayEntry? entry; Offset mouse = Offset.zero; // ... @override Widget build(BuildContext context) { return MouseRegion( onHover: (event) { setState(() => mouse = event.localPosition); entry?.markNeedsBuild(); }, child: Scaffold( // ... ), ); } }
OverlayEntry を生成して Navigator 経由で表示するOverlayEntry の builder 直下には Positioned を置くことができる remove() メソッドを呼び出すmarkNeedsBuild() メソッドを呼び出すOverlayを宣言的に扱うことができる
Positioned を挟むことができなかったので MouseRegion の例は再現できず😢
class _ContentsState extends State<Contents> { final random = math.Random(); int percentage = 0; bool showingOverlay = false; void tapped() => setState(() { percentage = random.nextInt(100); showingOverlay = true; }); @override Widget build(BuildContext context) { return PortalEntry( visible: showingOverlay, childAnchor: Alignment.topCenter, portalAnchor: Alignment.topCenter, portal: Material(child: Text('$percentage')), child: Scaffold( body: // ... ), ); } }class _ContentsState extends State<Contents> { final random = math.Random(); int percentage = 0; bool showingOverlay = false; void tapped() => setState(() { percentage = random.nextInt(100); showingOverlay = true; }); @override Widget build(BuildContext context) { return PortalEntry( visible: showingOverlay, childAnchor: Alignment.topCenter, portalAnchor: Alignment.topCenter, portal: Material(child: Text('$percentage')), child: Scaffold( body: // ... ), ); } }