Flutter覆盖层管理插件flutter_overlay_manager的使用
Flutter覆盖层管理插件flutter_overlay_manager的使用
flutter_overlay_manager
是一个用于管理Flutter应用中覆盖层(overlay)的插件。它将主UI与覆盖层分离,允许我们在不干扰主UI的情况下添加任何其他图层。这解决了在使用Navigator时遇到的一些问题,如路由管理、生命周期事件处理以及异步操作的复杂性等。
特性
- 内置加载指示器(loading overlay entry)
- 支持通过z-index排序
- 同一ID的覆盖层只会显示一个实例
安装
在pubspec.yaml
文件中添加依赖:
dependencies:
flutter_overlay_manager: ^<latest_version>
初始化
作为单例初始化:
FlutterOverlayManager overlayManager = FlutterOverlayManager.I;
或创建新实例:
FlutterOverlayManager overlayManager = FlutterOverlayManager.asNewInstance();
通常在MaterialApp的builder中调用以包裹整个应用程序来管理覆盖层:
MaterialApp(
builder: (context, child) {
return FlutterOverlayManager.I.builder((context) => child!);
},
home: YourHomePage(),
);
显示自定义覆盖层
可以将任意Widget作为覆盖层显示:
overlayManager.show(
(context) => YourCustomWidget(),
id:'your_overlay_entry_id',
zindex: 1, // 覆盖层的位置
backgroundColor: Colors.black54,
dismissible: true,
);
显示加载指示器
内置了加载指示器,用于防止用户在执行API调用或长时间运行任务期间与UI交互。确保任何时候只显示一个加载指示器:
OverlayEntryControl control = await overlayManager.showLoading();
// 或者自定义加载指示器
final control = await FlutterOverlayManager.I.showLoading(builder: (context) => CircularProgressIndicator());
隐藏加载指示器:
control.dismiss(); // 如果有控制引用
// 或者
overlayManager.hide(loadingId); // 如果没有控制引用
设置覆盖层位置
覆盖层的位置由z-index
决定,默认情况下加载指示器的z-index
为0。例如,要显示一个位于加载指示器之上的覆盖层,可以设置更高的z-index
值:
overlayManager.show(
(context) => const Positioned(
top: 200,
right: 0,
child: TopOverlayView(),
),
zindex: 1, // 加载指示器将在其下方
id: "_TOP_OVERLAY_ID",
);
隐藏覆盖层
通过ID隐藏特定覆盖层:
overlayManager.hide('your_overlay_id');
或者如果有控制引用,则可以直接调用dismiss()
方法。
示例代码
以下是一个完整的示例代码,展示了如何集成和使用flutter_overlay_manager
插件。
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_overlay_manager/flutter_overlay_manager.dart';
void main() {
FlutterOverlayManager.I.setLoadingZIndex(0);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
builder: (context, child) {
return FlutterOverlayManager.I.builder((context) => child!);
},
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FilledButton(
onPressed: () async {
final loader = await FlutterOverlayManager.I.showLoading();
await Future.delayed(Duration(seconds: 5));
await loader.dismiss();
},
child: Text("Long-running task"),
),
const SizedBox(height: 32),
FilledButton(
onPressed: () {
if (FlutterOverlayManager.I.isOverlayShowing("_TOP_OVERLAY_ID")) {
FlutterOverlayManager.I.hide("_TOP_OVERLAY_ID");
} else {
FlutterOverlayManager.I.show(
(context) => const Positioned(
top: 200,
right: 0,
child: TopOverlayView(),
),
zindex: 1, // 加载指示器将在其下方
id: "_TOP_OVERLAY_ID",
);
}
setState(() {});
},
child: Text(
FlutterOverlayManager.I.isOverlayShowing("_TOP_OVERLAY_ID")
? "Hide Top Overlay"
: "Show Top Overlay"),
),
],
),
),
);
}
}
class TopOverlayView extends StatefulWidget {
const TopOverlayView({super.key});
@override
State<TopOverlayView> createState() => _TopOverlayViewState();
}
class _TopOverlayViewState extends State<TopOverlayView> {
var _color = Colors.yellow;
void _randomColor() {
final random = Random();
_color = Colors.primaries[random.nextInt(Colors.primaries.length)];
setState(() {});
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
color: _color,
width: 50,
height: 50,
),
const SizedBox(height: 16),
FilledButton(
onPressed: () {
_randomColor();
},
child: Text("Click to change color"),
),
],
);
}
}
这个例子展示了如何在一个按钮点击后显示一个长时间运行的任务(模拟为延迟5秒),并在此期间显示加载指示器;另一个按钮用于切换顶部覆盖层的显示/隐藏状态。
更多关于Flutter覆盖层管理插件flutter_overlay_manager的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter覆盖层管理插件flutter_overlay_manager的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何使用 flutter_overlay_manager
插件的示例代码。这个插件允许你更轻松地管理 Flutter 应用中的覆盖层(Overlays)。
首先,确保你已经在 pubspec.yaml
文件中添加了 flutter_overlay_manager
依赖:
dependencies:
flutter:
sdk: flutter
flutter_overlay_manager: ^x.y.z # 替换为最新版本号
然后,运行 flutter pub get
来获取依赖。
接下来,你可以在你的 Flutter 应用中使用 flutter_overlay_manager
。以下是一个简单的示例,展示如何显示和隐藏一个覆盖层。
主应用代码
import 'package:flutter/material.dart';
import 'package:flutter_overlay_manager/flutter_overlay_manager.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: OverlayManagerProvider(
child: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final OverlayManager overlayManager = OverlayManager();
void _showOverlay() {
overlayManager.showOverlay(
context,
OverlayEntryBuilder(
builder: (context) {
return Positioned(
bottom: 20,
width: MediaQuery.of(context).size.width,
child: Container(
height: 100,
color: Colors.black54,
alignment: Alignment.center,
child: Text('This is an overlay!', style: TextStyle(color: Colors.white)),
),
);
},
),
);
}
void _hideOverlay() {
overlayManager.hideOverlay(context);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Overlay Manager Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
ElevatedButton(
onPressed: _showOverlay,
child: Text('Show Overlay'),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _hideOverlay,
tooltip: 'Hide Overlay',
child: Icon(Icons.clear),
),
);
}
}
解释
-
依赖提供:在
MyApp
中,我们使用OverlayManagerProvider
包裹根组件,以确保OverlayManager
在整个应用中可用。 -
OverlayManager 实例:在
MyHomePage
的状态中,我们创建了一个OverlayManager
实例。 -
显示覆盖层:在
_showOverlay
方法中,我们使用overlayManager.showOverlay
方法显示一个覆盖层。这个覆盖层包含一个Positioned
组件,它定位在屏幕底部,并包含一个文本。 -
隐藏覆盖层:在
_hideOverlay
方法中,我们使用overlayManager.hideOverlay
方法隐藏当前显示的覆盖层。 -
UI 组件:在
build
方法中,我们创建了一个简单的 UI,包含一个按钮来显示覆盖层和一个浮动操作按钮来隐藏覆盖层。
这个示例展示了如何使用 flutter_overlay_manager
插件来管理覆盖层。你可以根据需要扩展和修改这个示例以适应你的具体需求。