有时候我们在开发APP的时候会遇到下面这些需求:
当需要在 Flutter 应用中在现有 UI 层上添加新的视图或交互时,可以使用 Overlay 组件。Overlay 允许将一个或多个小部件(称为 OverlayEntry)叠加在应用的现有 UI 上。
Overlay包括两个基本组件:OverlayState和OverlayEntry。OverlayState管理所有OverlayEntry,OverlayEntry定义覆盖层的内容。
下面通过一个简单的例子来说明:例子要实现点击一个按钮会打开Overlay显示一个FloatingActionButton。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Overlay Example'),
),
body: Center(
child: ElevatedButton(
child: Text('Open Overlay'),
onPressed: () {
showFloatingButtonOverlay(context);
},
),
),
),
);
}
}
void showFloatingButtonOverlay(BuildContext context) {
OverlayState? overlayState = Overlay.of(context);
late OverlayEntry overlayEntry;
// 创建 OverlayEntry
overlayEntry = OverlayEntry(
builder: (BuildContext context) {
return Positioned(
top: 100,
right: 16,
child: FloatingActionButton(
onPressed: () {
// 悬浮按钮被点击
print('Floating Button Clicked');
overlayEntry.remove(); // 移除 OverlayEntry
},
child: Icon(Icons.add),
),
);
},
);
// 将 OverlayEntry 添加到 Overlay 中
overlayState?.insert(overlayEntry);
}
运行结果如图:
本来想直接贴正确的代码的,但是觉得这个错误对初学者来说很容易犯,故单独列出来。
点击Open Overlay按钮报错No Overlay widget found。如下图
该错误提示是因为在使用 Overlay.of(context) 方法时,找不到可用的 Overlay 对象。
确保按钮所在的 BuildContext 对象正确。在上述示例中,按钮的 onPressed 回调中使用的 BuildContext 应该是 Scaffold 的上下文,确保按钮在正确的上下文中定义和使用。
确保 Overlay 被正确地放置在应用的组件树中。在上述示例中,Overlay 组件应该在 MaterialApp 或 WidgetsApp 的下方,以确保它们在正确的层次结构中。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: OverlayExample(), // 使用 OverlayExample 作为主页
);
}
}
class OverlayExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Overlay Example'),
),
body: Center(
child: ElevatedButton(
child: Text('Open Overlay'),
onPressed: () {
showFloatingButtonOverlay(context);
},
),
),
);
}
}
void showFloatingButtonOverlay(BuildContext context) {
OverlayState? overlayState = Overlay.of(context);
late OverlayEntry overlayEntry;
// 创建 OverlayEntry
overlayEntry = OverlayEntry(
builder: (BuildContext context) {
return Positioned(
top: 100,
right: 16,
child: FloatingActionButton(
onPressed: () {
// 悬浮按钮被点击
print('Floating Button Clicked');
overlayEntry.remove(); // 移除 OverlayEntry
},
child: Icon(Icons.add),
),
);
},
);
// 将 OverlayEntry 添加到 Overlay 中
overlayState?.insert(overlayEntry);
}