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: // ... ), ); } }