Flutter加载覆盖层插件loader_overlay的使用
Flutter加载覆盖层插件loader_overlay的使用
loader_overlay
是一个用于Flutter应用的插件,它允许开发者在执行异步操作时显示一个加载遮罩层(overlay),以防止用户在此期间与屏幕交互。这个插件非常适合用来提升用户体验,尤其是在网络请求或复杂计算正在进行的时候。下面将详细介绍如何使用 loader_overlay
插件,并提供完整的示例代码。
一、基本用法
1. 引入依赖
首先,在你的 pubspec.yaml
文件中添加 loader_overlay
作为依赖:
dependencies:
flutter:
sdk: flutter
loader_overlay: ^3.0.0 # 确保使用最新版本
然后运行 flutter pub get
来安装插件。
2. 使用LoaderOverlay包裹页面
接下来,在需要展示加载遮罩的地方使用 LoaderOverlay
包裹住整个页面。例如:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LoaderOverlay(
child: MyHomePage(title: 'Flutter Demo Home Page'),
),
);
}
}
此时,你已经配置好了加载遮罩功能,但还没有实际显示出来。
3. 显示和隐藏加载遮罩
要显示加载遮罩,只需调用:
context.loaderOverlay.show();
这会显示默认的圆形进度指示器。如果你想隐藏它,可以调用:
context.loaderOverlay.hide();
此外,还可以通过以下方式检查遮罩是否可见:
final isVisible = context.loaderOverlay.visible;
注意:每次显示或隐藏遮罩都需要有有效的 BuildContext
。
二、导航中的全局使用
如果你希望在整个应用程序中都能使用加载遮罩,而不仅仅是在某个特定页面上,那么可以考虑使用 GlobalLoaderOverlay
。它的工作原理类似于 LoaderOverlay
,只不过它是作用于所有路由上的。
return GlobalLoaderOverlay(
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.teal, fontFamily: 'Baloo'),
initialRoute: '/',
routes: {
'/': (context) => Page1(),
'/page2': (context) => Page2(),
},
),
);
三、自定义加载遮罩样式
除了默认的圆形进度条外,你还可以根据需求自定义加载遮罩的外观。比如,你可以引入 flutter_spinkit
这样的动画库来创建更有趣的加载效果。
LoaderOverlay(
useDefaultLoading: false,
overlayWidgetBuilder: (_) {
return Center(
child: SpinKitCubeGrid(
color: Colors.red,
size: 50.0,
),
);
},
child: MyHomePage(title: 'Flutter Demo Home Page'),
),
同时,也可以调整遮罩的颜色和透明度:
overlayColor: Colors.yellow.withOpacity(0.8),
四、带有进度信息的加载遮罩
有时候我们可能想要向用户传达当前任务的具体进展情况。这时可以通过传递 progress
参数给 show()
方法,并在 overlayWidgetBuilder
中处理这些信息。
context.loaderOverlay.show(
progress: 'Doing progress #0',
);
await Future.delayed(Duration(seconds: 1));
context.loaderOverlay.progress('Doing progress #1');
// ...
五、完整示例
最后,这里给出一个包含上述所有特性的完整例子:
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:loader_overlay/loader_overlay.dart';
void main() => runApp(const MyAppGlobalLoaderOverlay());
class MyAppGlobalLoaderOverlay extends StatelessWidget {
const MyAppGlobalLoaderOverlay({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return GlobalLoaderOverlay(
duration: const Duration(milliseconds: 250),
reverseDuration: const Duration(milliseconds: 250),
overlayColor: Colors.grey.withAlpha(204), // 设置为半透明灰色
overlayWidgetBuilder: (_) {
return const Center(
child: SpinKitCubeGrid(
color: Colors.red,
size: 50.0,
),
);
},
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primaryColor: Colors.black,
fontFamily: 'Baloo',
),
initialRoute: '/',
routes: {
'/': (context) => const MyHomePage(),
},
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isLoaderVisible = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () async {
context.loaderOverlay.show();
setState(() {
_isLoaderVisible = context.loaderOverlay.visible;
});
await Future.delayed(const Duration(seconds: 2));
if (_isLoaderVisible && context.mounted) {
context.loaderOverlay.hide();
}
setState(() {
_isLoaderVisible = context.loaderOverlay.visible;
});
},
child: const Text('Show overlay for 2 seconds'),
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () async {
context.loaderOverlay.show(
widgetBuilder: (progress) {
return ReconnectingOverlay(
progress != null ? progress as String : null,
);
},
progress: 'Trying to reconnect');
setState(() {
_isLoaderVisible = context.loaderOverlay.visible;
});
await Future.delayed(const Duration(seconds: 3));
if (_isLoaderVisible && context.mounted) {
context.loaderOverlay.hide();
}
setState(() {
_isLoaderVisible = context.loaderOverlay.visible;
});
},
child: const Text('Show custom loader overlay for 3 seconds'),
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () async {
context.loaderOverlay.show(
progress: 'Doing progress #0',
);
setState(() {
_isLoaderVisible = context.loaderOverlay.visible;
});
await Future.delayed(const Duration(seconds: 1));
if (context.mounted) {
context.loaderOverlay.progress('Doing progress #1');
}
await Future.delayed(const Duration(seconds: 1));
if (context.mounted) {
context.loaderOverlay.progress('Doing progress #2');
}
await Future.delayed(const Duration(seconds: 1));
if (context.mounted) {
context.loaderOverlay.progress('Doing progress #3');
}
await Future.delayed(const Duration(seconds: 1));
if (_isLoaderVisible && context.mounted) {
context.loaderOverlay.hide();
}
setState(() {
_isLoaderVisible = context.loaderOverlay.visible;
});
},
child:
const Text('Show loader overlay for 5 seconds with progress'),
),
const SizedBox(height: 34),
Text('Is loader visible: $_isLoaderVisible'),
],
),
),
);
}
}
class ReconnectingOverlay extends StatelessWidget {
final String? progress;
const ReconnectingOverlay(this.progress, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => Center(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const CircularProgressIndicator(),
const SizedBox(height: 12),
const Text(
'Reconnecting...',
),
const SizedBox(height: 12),
Text(
progress ?? '',
),
],
),
);
}
以上就是关于 loader_overlay
插件的基本介绍及其使用方法。通过合理运用该插件,可以使我们的应用程序更加友好且专业。如果有任何问题或者建议,请参考官方文档或前往GitHub仓库提交issue。
更多关于Flutter加载覆盖层插件loader_overlay的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter加载覆盖层插件loader_overlay的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用loader_overlay
插件的示例代码。这个插件通常用于在应用执行某些耗时操作时显示一个加载覆盖层,以提高用户体验。
首先,确保你已经在pubspec.yaml
文件中添加了loader_overlay
依赖:
dependencies:
flutter:
sdk: flutter
loader_overlay: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来获取依赖。
接下来,你可以在你的Flutter应用中这样使用loader_overlay
:
import 'package:flutter/material.dart';
import 'package:loader_overlay/loader_overlay.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: LoaderOverlayExample(),
);
}
}
class LoaderOverlayExample extends StatefulWidget {
@override
_LoaderOverlayExampleState createState() => _LoaderOverlayExampleState();
}
class _LoaderOverlayExampleState extends State<LoaderOverlayExample> with LoaderOverlayMixin {
bool isLoading = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Loader Overlay Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Tap the button to show the loader overlay'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
setState(() {
isLoading = true;
});
// Simulate a time-consuming task
await Future.delayed(Duration(seconds: 3));
setState(() {
isLoading = false;
});
},
child: Text('Show Loader'),
),
],
),
),
// Add the LoaderOverlay widget here
loaderOverlay: LoaderOverlay(
isActive: isLoading,
color: Colors.black.withOpacity(0.5),
child: Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
),
),
);
}
}
代码说明:
-
依赖导入:
import 'package:loader_overlay/loader_overlay.dart';
:导入loader_overlay
包。
-
使用
LoaderOverlayMixin
:- 通过
with LoaderOverlayMixin
在状态类中混合使用LoaderOverlayMixin
,这允许你控制加载覆盖层的显示状态。
- 通过
-
构建UI:
- 使用
Scaffold
构建应用的基本布局。 - 添加一个按钮,当按钮被点击时,
isLoading
状态变为true
,模拟一个耗时操作(通过Future.delayed
),然后isLoading
状态变为false
。
- 使用
-
加载覆盖层:
- 在
Scaffold
的loaderOverlay
属性中添加LoaderOverlay
。 isActive
属性绑定到isLoading
状态,当isLoading
为true
时显示加载覆盖层。- 自定义加载覆盖层的颜色和子元素(例如,一个居中的
CircularProgressIndicator
)。
- 在
这样,当按钮被点击时,加载覆盖层会显示出来,并在模拟的耗时操作完成后隐藏。希望这个示例对你有帮助!