Flutter弹出层插件popover的使用
Flutter弹出层插件popover的使用
内容目录
Features
一个弹出层(Popover)是一种短暂视图,当您点击某个控件或屏幕上的某个区域时出现。通常,弹出层包含一个指向其出现位置的箭头。弹出层可以是非模态或模态的。非模态弹出层通过点击屏幕其他部分或弹出层上的按钮来关闭;模态弹出层则通过点击“取消”或其他按钮来关闭。
Requirements
- Dart: 3.5.0+
- Flutter: 3.24.0+
Install
在pubspec.yaml
文件中添加依赖:
dependencies:
popover: ^0.3.1
Example
以下是使用popover
插件的一个完整示例:
示例代码
import 'package:flutter/material.dart';
import 'package:popover/popover.dart';
void main() => runApp(PopoverExample());
class PopoverExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Popover Example')),
body: const SafeArea(
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
Button(),
Button(),
Button(),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
Button(),
Button(),
Button(),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
Button(),
Button(),
Button(),
],
),
],
),
),
),
),
);
}
}
class Button extends StatelessWidget {
const Button({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: 80,
height: 40,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5)),
boxShadow: [BoxShadow(color: Colors.black26, blurRadius: 5)],
),
child: GestureDetector(
child: const Center(child: Text('Click Me')),
onTap: () {
showPopover(
context: context,
bodyBuilder: (context) => const ListItems(),
onPop: () => print('Popover was popped!'),
direction: PopoverDirection.bottom,
backgroundColor: Colors.white,
width: 200,
height: 400,
arrowHeight: 15,
arrowWidth: 30,
);
},
),
);
}
}
class ListItems extends StatelessWidget {
const ListItems({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: ListView(
padding: const EdgeInsets.all(8),
children: [
InkWell(
onTap: () {
Navigator.of(context)
..pop()
..push(
MaterialPageRoute<SecondRoute>(
builder: (context) => SecondRoute(),
),
);
},
child: Container(
height: 50,
color: Colors.amber[100],
child: const Center(child: Text('Entry A')),
),
),
const Divider(),
Container(
height: 50,
color: Colors.amber[200],
child: const Center(child: Text('Entry B')),
),
const Divider(),
Container(
height: 50,
color: Colors.amber[300],
child: const Center(child: Text('Entry C')),
),
const Divider(),
Container(
height: 50,
color: Colors.amber[400],
child: const Center(child: Text('Entry D')),
),
const Divider(),
Container(
height: 50,
color: Colors.amber[500],
child: const Center(child: Text('Entry E')),
),
const Divider(),
Container(
height: 50,
color: Colors.amber[600],
child: const Center(child: Text('Entry F')),
),
],
),
);
}
}
class SecondRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Second Route'),
automaticallyImplyLeading: false,
),
body: Center(
child: ElevatedButton(
onPressed: () => Navigator.pop(context),
child: const Text('Back'),
),
),
);
}
}
运行示例
要在一个设备或模拟器上查看此包的示例,请执行以下命令:
cd example && flutter run
Support
如果您有任何问题或功能请求,请在GitHub的issue tracker上发布。
License
Popover项目的源代码在MIT许可证下提供。更多信息请参阅LICENSE文件。
更多关于Flutter弹出层插件popover的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter弹出层插件popover的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用popover
弹出层插件的示例代码。需要注意的是,Flutter本身并没有直接提供一个名为popover
的官方插件,但我们可以使用第三方库或者自定义一个类似的弹出层效果。在这个示例中,我们将使用flutter_popover
这个第三方库(假设它存在,实际情况中你可能需要查找一个合适的库或自己实现)。
首先,你需要在pubspec.yaml
文件中添加依赖项(这里以flutter_popover
为例,实际名称和版本号请根据实际情况调整):
dependencies:
flutter:
sdk: flutter
flutter_popover: ^x.y.z # 替换为实际版本号
然后,运行flutter pub get
来安装依赖。
接下来,我们编写一个简单的Flutter应用,展示如何使用这个弹出层插件。
import 'package:flutter/material.dart';
import 'package:flutter_popover/flutter_popover.dart'; // 假设库名为flutter_popover
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Popover Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
PopoverController? popoverController;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Popover Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Tap the button to show a popover',
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
showPopover(context);
},
child: Text('Show Popover'),
),
],
),
),
);
}
void showPopover(BuildContext context) {
popoverController = PopoverController(context: context);
popoverController?.showPopover(
Popover(
child: Container(
padding: EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.0),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('This is a popover'),
SizedBox(height: 10),
ElevatedButton(
onPressed: () {
popoverController?.hidePopover();
},
child: Text('Close'),
),
],
),
),
arrowDecoration: BoxDecoration(
color: Colors.white,
),
arrowDirection: ArrowDirection.down,
),
arrowOffset: Offset(0, 10),
popoverOffset: Offset(0, 10),
);
}
}
注意:上面的代码是一个假设性的示例,因为实际上并没有一个直接名为flutter_popover
的官方插件。如果你找不到合适的第三方库,你可以考虑自己实现一个弹出层效果,使用Overlay
和AnimatedPositioned
等Flutter提供的组件。
如果你需要自己实现,以下是一个简单的自定义弹出层示例:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Custom Popover Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
OverlayEntry? _overlayEntry;
AnimationController? _controller;
Animation<Offset>? _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
_animation = Tween<Offset>(
begin: Offset.zero,
end: Offset(0, 1),
).animate(
CurvedAnimation(
parent: _controller!,
curve: Curves.easeInOut,
),
);
}
@override
void dispose() {
_controller?.dispose();
_overlayEntry?.remove();
super.dispose();
}
void _showPopover(BuildContext context) {
final RenderBox overlay = context.findRenderObject()! as RenderBox;
final Offset offset = overlay.localToGlobal(Offset.zero);
_overlayEntry = OverlayEntry(
builder: (context) => SlideTransition(
position: _animation!,
child: Material(
elevation: 4.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
child: Container(
margin: EdgeInsets.only(top: offset.dy + 10),
padding: EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('This is a custom popover'),
SizedBox(height: 10),
ElevatedButton(
onPressed: () {
_controller?.reverse();
_overlayEntry?.remove();
_overlayEntry = null;
},
child: Text('Close'),
),
],
),
),
),
),
);
Overlay.of(context)!.insert(_overlayEntry!);
_controller?.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Custom Popover Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Tap the button to show a custom popover'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () => _showPopover(context),
child: Text('Show Popover'),
),
],
),
),
);
}
}
这个自定义弹出层的示例使用了Overlay
和SlideTransition
来实现弹出效果。你可以根据需要调整动画和样式。