Flutter屏障插件barrier_around的使用
Flutter屏障插件barrier_around的使用
Barrier Around
一个可以在任何位置为任意小部件创建屏障的Flutter插件。
解决什么问题?
有时我们需要突出显示或展示特定的小部件。如果该小部件是Stack的直接子项,这很容易实现。但是,如果我们想围绕一个嵌套在例如Column中的特定小部件创建一个屏障,这将变得非常复杂。我们可以通过计算位置和大小来尝试实现,但这种方法很快就会变得混乱。
使用方法
要使用此插件,在你的pubspec.yaml
文件中添加barrier_around
作为依赖项。
dependencies:
barrier_around: ^x.x.x
示例
首先,创建一个GlobalKey
以标识你想要创建屏障的小部件。
final GlobalKey _barrierKey = GlobalKey();
接下来,将你想要创建屏障的小部件包装在一个BarrierAround
小部件中,并为其分配GlobalKey
。
BarrierAround(
key: _barrierKey,
child: yourWidget
)
当你想要显示屏障时,只需调用:
BarrierAroundManager.showBarrier(_barrierKey);
要关闭屏障,只需点击它即可,这种行为默认启用。如果你希望屏障在点击时不消失,可以在BarrierAround
小部件中设置dismissOnBarrierTap
为false
。
如果你想从其他地方关闭屏障,只需调用:
BarrierAroundManager.dismissBarrier(_barrierKey);
屏障自定义
你可以通过以下属性来自定义屏障:
名称 | 类型 | 描述 | 默认值 |
---|---|---|---|
barrierBorderRadius |
BorderRadius? |
如果你的小部件有圆角,则在这里设置 | null |
barrierColor |
Color |
屏障的颜色 | Colors.black45 |
barrierOpacity |
double |
屏障的不透明度 | 0.75 |
barrierBlur |
double? |
屏障的模糊程度 | null |
targetPadding |
EdgeInsets |
目标小部件周围的填充 | EdgeInsets.zero |
onBarrierTap |
VoidCallback? |
点击屏障的回调 | null |
dismissOnBarrierTap |
bool |
当用户点击屏障时是否应该消失 | true |
animateBarrier |
bool |
显示/隐藏屏障时是否需要动画 | true |
animationDuration |
Duration |
如果animateBarrier 为true ,你可以在这里指定动画持续时间 |
Duration(milliseconds: 150) |
建议和贡献
如果你有任何关于代码改进、错误修复、新功能的建议,或者希望以任何方式做出贡献,请在GitHub上提出问题或私信我Twitter。
完整示例代码
import 'package:barrier_around/barrier_around.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'BarrierAround Example',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Scaffold(
body: SafeArea(
child: Center(
child: BarrierAroundShowcase(),
),
),
),
);
}
}
class BarrierAroundShowcase extends StatefulWidget {
const BarrierAroundShowcase({super.key});
[@override](/user/override)
State<BarrierAroundShowcase> createState() => _BarrierAroundShowcaseState();
}
class _BarrierAroundShowcaseState extends State<BarrierAroundShowcase> {
static const textStyle = TextStyle(
fontSize: 18.0,
color: Colors.white,
fontWeight: FontWeight.bold,
);
final GlobalKey _redContainerBarrier = GlobalKey();
final GlobalKey _greenContainerBarrier = GlobalKey();
final GlobalKey _blueContainerBarrier = GlobalKey();
bool tapped = false;
[@override](/user/override)
void initState() {
super.initState();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
_createRedContainer(),
const SizedBox(height: 16.0),
_createGreenContainer(),
const SizedBox(height: 16.0),
_createBlueContainer(),
],
),
);
}
_createRedContainer() {
return Expanded(
child: GestureDetector(
onTap: () {
BarrierAroundManager.showBarrier(_redContainerBarrier);
},
child: BarrierAround(
key: _redContainerBarrier,
animateBarrier: false,
child: Container(
padding: const EdgeInsets.all(16.0),
color: Colors.red.withOpacity(0.9),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: const [
Text(
"Animate: false",
style: textStyle,
),
Text(
"Barrier blur: 0.0",
style: textStyle,
),
],
),
),
),
),
);
}
_createGreenContainer() {
return Expanded(
child: GestureDetector(
onTap: () {
BarrierAroundManager.showBarrier(_greenContainerBarrier);
},
child: BarrierAround(
key: _greenContainerBarrier,
barrierBorderRadius: BorderRadius.circular(16.0),
barrierBlur: 15.0,
animationDuration: const Duration(seconds: 1),
onBarrierTap: () {
setState(() {
tapped = true;
});
Future.delayed(const Duration(seconds: 2), () {
setState(() {
tapped = false;
});
});
},
child: Container(
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.green.withOpacity(0.9),
borderRadius: BorderRadius.circular(16.0),
),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text(
"Animate: true",
style: textStyle,
),
const Text(
"Animation duration: 1 second",
style: textStyle,
),
const Text(
"Barrier blur: 15.0",
style: textStyle,
),
const Text(
"Barrier border radius: 16.0",
style: textStyle,
),
Text(
!tapped
? "onBarrierTap: Not tapped yet..."
: "onBarrierTap: TAPPED!",
style: textStyle,
),
],
),
),
),
),
);
}
_createBlueContainer() {
return Expanded(
child: GestureDetector(
onTap: () {
BarrierAroundManager.showBarrier(_blueContainerBarrier);
},
child: BarrierAround(
key: _blueContainerBarrier,
barrierBorderRadius: BorderRadius.circular(32.0),
barrierBlur: 5.0,
barrierColor: Colors.teal,
targetPadding: const EdgeInsets.all(4.0),
child: Container(
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.blue.withOpacity(0.9),
borderRadius: BorderRadius.circular(32.0),
),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: const [
Text(
"Animate: true",
style: textStyle,
),
Text(
"Barrier blur: 5.0",
style: textStyle,
),
Text(
"Barrier border radius: 32.0",
style: textStyle,
),
Text(
"Barrier color: teal",
style: textStyle,
),
Text(
"Target padding: 4.0",
style: textStyle,
),
],
),
),
),
),
);
}
}
更多关于Flutter屏障插件barrier_around的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter屏障插件barrier_around的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用barrier_around
插件的一个示例。barrier_around
是一个Flutter插件,它允许你在指定的widget周围添加一个半透明的屏障。这在创建模态对话框、聚焦特定区域等场景中非常有用。
首先,你需要在你的pubspec.yaml
文件中添加barrier_around
依赖:
dependencies:
flutter:
sdk: flutter
barrier_around: ^latest_version # 请替换为实际的最新版本号
然后运行flutter pub get
来安装依赖。
接下来是一个完整的示例,展示如何使用barrier_around
:
import 'package:flutter/material.dart';
import 'package:barrier_around/barrier_around.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Barrier Around Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isBarrierVisible = false;
void _toggleBarrier() {
setState(() {
_isBarrierVisible = !_isBarrierVisible;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Barrier Around Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You can click the button to toggle the barrier around the focused widget.',
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _toggleBarrier,
child: Text('Toggle Barrier'),
),
SizedBox(height: 40),
BarrierAround(
visible: _isBarrierVisible,
color: Colors.black.withOpacity(0.5),
barrierConstraints: BoxConstraints(
minHeight: 200,
minWidth: 200,
),
child: FocusWidget(),
),
],
),
),
);
}
}
class FocusWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.lightBlue,
borderRadius: BorderRadius.circular(16),
),
padding: EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'This is the focused widget.',
style: TextStyle(fontSize: 20, color: Colors.white),
),
SizedBox(height: 10),
ElevatedButton(
onPressed: () {},
child: Text('Click Me', style: TextStyle(color: Colors.white)),
),
],
),
);
}
}
在这个示例中:
MyApp
是我们的主应用类,它包含了一个MaterialApp
。MyHomePage
是我们的主页面,它包含一个按钮和一个BarrierAround
widget。_toggleBarrier
方法用于切换屏障的可见性。BarrierAround
widget包裹了一个FocusWidget
,当屏障可见时,它会围绕FocusWidget
显示一个半透明的屏障。FocusWidget
是我们想要聚焦的widget,它包含了一些文本和一个按钮。
你可以根据需要调整BarrierAround
的参数,例如color
和barrierConstraints
,以符合你的应用需求。