Flutter自定义指向弹出框插件custom_pointed_popup的使用
Flutter自定义指向弹出框插件custom_pointed_popup的使用
简介
custom_pointed_popup
是一个Flutter插件,允许你在任何目标小部件上显示带有自定义指针设计的弹出框。这个插件提供了丰富的自定义选项,包括背景颜色、指针方向、边框半径等。
截图
以下是该插件的效果图:
使用示例
1. 添加依赖
首先,在你的 pubspec.yaml
文件中添加 custom_pointed_popup
依赖:
dependencies:
custom_pointed_popup: ^最新版本号
然后运行 flutter pub get
来安装依赖。
2. 完整示例代码
以下是一个完整的示例代码,展示了如何使用 custom_pointed_popup
插件:
import 'package:custom_pointed_popup/custom_pointed_popup.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blueGrey,
),
home: Home(),
);
}
}
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
[@override](/user/override)
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final GlobalKey widgetKey = GlobalKey();
CustomPointedPopup getCustomPointedPopup(BuildContext context) {
return CustomPointedPopup(
backgroundColor: Colors.red, // 弹出框的背景颜色
context: context, // 当前上下文
widthFractionWithRespectToDeviceWidth: 3, // 弹出框宽度相对于设备宽度的比例
triangleDirection: TriangleDirection.FullLeft, // 指针方向
popupElevation: 10, // 弹出框的阴影高度
displayBelowWidget: true, // 是否显示在目标小部件下方
customHeight: 150, // 弹出框的高度
/// 你可以添加边框半径
// popupBorderRadius: BorderRadius.circular(10),
item: CustomPointedPopupItem(
title: 'Popup that can be shown on any targeted widget with customized pointed design.', // 弹出框的标题
textStyle: Theme.of(context).textTheme.caption!.copyWith(
color: Theme.of(context).cardColor, // 标题文本样式
),
iconWidget: Icon(
Icons.add_moderator, // 弹出框中的图标
color: Theme.of(context).cardColor,
),
/// 或者你可以添加自定义的小部件代替上面的三个属性
// itemWidget: Container(
// child: Center(
// child: Text('Custom item'),
// ),
// ),
),
onClickWidget: (onClickMenu) {
print('popup item clicked'); // 点击弹出框时的回调
},
onDismiss: () {
print('on dismissed called'); // 弹出框关闭时的回调
},
);
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Custom Pointed Popup [CPP]',
),
),
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'CPP with straight pointer & item.',
style: TextStyle(
color: Colors.red,
fontSize: 14.0,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 40,
),
GestureDetector(
onTap: () {
getCustomPointedPopup(context)
..show(
widgetKey: widgetKey, // 目标小部件的全局键
);
},
child: Card(
key: widgetKey, // 目标小部件的全局键
elevation: 10,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
child: Container(
height: 100,
width: 100,
child: Center(
child: Text(
'Click Me \nTo\n Display CPP',
textAlign: TextAlign.center,
overflow: TextOverflow.clip,
style: TextStyle(
color: Colors.blueGrey,
fontWeight: FontWeight.w900,
fontSize: 14.0,
),
),
),
),
),
),
],
),
),
),
);
}
}
更多关于Flutter自定义指向弹出框插件custom_pointed_popup的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自定义指向弹出框插件custom_pointed_popup的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中自定义和使用一个指向弹出框插件 custom_pointed_popup
的示例代码。请注意,实际使用时,你可能需要先在你的 pubspec.yaml
文件中添加该插件的依赖项(假设该插件存在并且已经在pub.dev上发布)。由于 custom_pointed_popup
并非官方或广泛认知的插件,以下示例将展示一个类似的自定义实现。
1. 添加依赖项(假设插件存在)
首先,在 pubspec.yaml
文件中添加依赖项(如果插件真实存在):
dependencies:
flutter:
sdk: flutter
custom_pointed_popup: ^x.y.z # 替换为实际版本号
然后运行 flutter pub get
。
2. 自定义指向弹出框的实现(如果插件不存在)
如果 custom_pointed_popup
插件不存在,你可以自己实现一个类似的弹出框。以下是一个简单的实现示例:
创建一个指向弹出框组件
import 'package:flutter/material.dart';
class PointedPopup extends StatelessWidget {
final Offset point; // 指向的位置
final Widget child; // 弹出框内容
const PointedPopup({Key? key, required this.point, required this.child})
: super(key: key);
@override
Widget build(BuildContext context) {
final RenderBox? overlayBox = context.findRenderObject();
final overlayOffset = overlayBox?.localToGlobal(Offset.zero) ?? Offset.zero;
final targetPosition = overlayOffset + point;
return Positioned(
left: targetPosition.dx - 50, // 调整位置以适应箭头
top: targetPosition.dy + 20, // 调整位置以适应箭头和内容
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
_Arrow(direction: ArrowDirection.down),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
padding: EdgeInsets.all(16),
child: child,
),
],
),
);
}
}
enum ArrowDirection { up, down, left, right }
class _Arrow extends StatelessWidget {
final ArrowDirection direction;
const _Arrow({Key? key, required this.direction}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border(
bottom: direction == ArrowDirection.up
? BorderSide(color: Colors.grey.shade300, width: 2)
: BorderSide.none,
top: direction == ArrowDirection.down
? BorderSide(color: Colors.grey.shade300, width: 2)
: BorderSide.none,
left: direction == ArrowDirection.right
? BorderSide(color: Colors.grey.shade300, width: 2)
: BorderSide.none,
right: direction == ArrowDirection.left
? BorderSide(color: Colors.grey.shade300, width: 2)
: BorderSide.none,
),
shape: BoxShape.rectangle,
),
child: Padding(
padding: EdgeInsets.only(
bottom: direction == ArrowDirection.up ? 8 : 0,
top: direction == ArrowDirection.down ? 8 : 0,
left: direction == ArrowDirection.right ? 8 : 0,
right: direction == ArrowDirection.left ? 8 : 0,
),
child: Transform.rotate(
angle: direction == ArrowDirection.up
? -math.pi / 2
: direction == ArrowDirection.down
? math.pi / 2
: direction == ArrowDirection.left
? math.pi
: 0,
child: Container(
width: 16,
height: 8,
decoration: BoxDecoration(
color: Colors.grey.shade300,
),
),
),
),
);
}
}
使用指向弹出框组件
import 'package:flutter/material.dart';
import 'pointed_popup.dart'; // 假设你将上面的代码保存在pointed_popup.dart文件中
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Pointed Popup Example'),
),
body: Center(
child: Stack(
children: <Widget>[
Positioned(
top: 200,
left: 150,
child: GestureDetector(
onTap: () {
showMenu(
context: context,
position: RelativeRect.fromLTRB(
100, // 根据需要调整
250, // 根据需要调整
300, // 根据需要调整
350, // 根据需要调整
),
items: <PopupMenuEntry<void>>[
PopupMenuItem<void>(
child: StatefulBuilder(
builder: (BuildContext context, void Function(void) setState) {
Offset? point;
return GestureDetector(
onTapDown: (details) {
point = details.globalPosition;
setState(() {});
},
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
if (point != null)
PointedPopup(
point: point!,
child: Container(
color: Colors.transparent,
child: Text('Hello, this is a pointed popup!'),
),
),
SizedBox(height: 20), // 为了展示点击效果,添加一些间距
Text('Tap me to show popup'),
],
),
);
},
),
),
],
);
},
child: Text('Show Popup'),
),
),
],
),
),
),
);
}
}
在这个示例中,我们创建了一个简单的指向弹出框组件 PointedPopup
,并在点击文本时显示它。这个示例并没有使用实际的 custom_pointed_popup
插件,而是展示了如何自定义一个类似的组件。如果你有一个具体的 custom_pointed_popup
插件,你应该参考其文档来了解如何使用。