我试图让一个覆盖如这里显示:
https://www.didierboelens.com/2018/06/how-to-create-a-toast-or-notifications-notion-of-overlay/
使用OverlayEntry。
import 'package:flutter/material.dart';
import 'dart:async';
class ShowNotificationIcon {
void show(BuildContext context) async {
OverlayState overlayState = Overlay.of(context);
OverlayEntry overlayEntry = new OverlayEntry(builder: _build);
overlayState.insert(overlayEntry);
}
Widget _build(BuildContext context){
return new Positioned(
top: 50.0,
left: 50.0,
child: new Material(
color: Colors.transparent,
child: new Icon(Icons.warning, color: Colors.purple),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
调用:
ShowNotificationIcon _icon = new ShowNotificationIcon();
_icon.show(context);
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试导航到其他屏幕时,叠加层仍保留在屏幕中。
如何仅在被调用的屏幕中显示覆盖而不在其他屏幕中显示?
以防万一,这是我在有状态小部件中尝试过的:
ShowNotificationIcon _icon = new ShowNotificationIcon();
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
_icon.show(context);
});
super.initState();
}
@override
void dispose() {
_icon.remove();
super.dispose();
}
Run Code Online (Sandbox Code Playgroud)
这通常使用RouteAware+执行RouteObserver。
RouteObserver是一个对象,它让实现的对象RouteAware对与路由相关的一些更改做出反应,其中包括:
然后您可以使用这两个事件来隐藏/显示您的叠加层
首先,您需要一个RouteObserver.
这可以创建为全局变量,并且需要传递给您的Navigator. 在MaterialApp基于应用程序中,它通常如下所示:
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
void main() {
runApp(MaterialApp(
home: Container(),
navigatorObservers: [routeObserver],
));
}
Run Code Online (Sandbox Code Playgroud)
然后,拥有 的小部件OverlayEntry现在可以RouteAware像这样实现:
class RouteAwareWidget extends StatefulWidget {
State<RouteAwareWidget> createState() => RouteAwareWidgetState();
}
// Implement RouteAware in a widget's state and subscribe it to the RouteObserver.
class RouteAwareWidgetState extends State<RouteAwareWidget> with RouteAware {
@override
void didChangeDependencies() {
super.didChangeDependencies();
// routeObserver is the global variable we created before
routeObserver.subscribe(this, ModalRoute.of(context));
}
@override
void dispose() {
routeObserver.unsubscribe(this);
super.dispose();
}
@override
void didPush() {
// Route was pushed onto navigator and is now topmost route.
}
@override
void didPopNext() {
// Covering route was popped off the navigator.
}
@override
Widget build(BuildContext context) => Container();
}
Run Code Online (Sandbox Code Playgroud)
此时,您可以使用didPush和didPopNext来显示/隐藏您的 OverlayEntry:
OverlayEntry myOverlay;
@override
void didPush() {
myOverlay.remove();
}
@override
void didPopNext() {
Overlay.of(context).insert(myOverlay);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4922 次 |
| 最近记录: |