1,实现效果:
2,关键代码:
//1.定义一个全局key
GlobalKey anchorKey = GlobalKey();
Text(
'context',
key:anchorKey // 2.绑定key
);
//3. 获取到当前context
var renderBox = anchorKey.currentContext?.findRenderObject() as RenderBox;
//4. 获取到当前dom元素坐标
var offset = renderBox.globalToLocal(Offset(100, renderBox.size.height));
3.完整代码
import 'package:flutter/material.dart';
class AskQuestionPage extends StatefulWidget {
@override
State createState() => _AskQuestionPageState();
}
class _AskQuestionPageState extends State {
//定义一个全局key (关键代码!!)
GlobalKey anchorKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Column(
children: [
SizedBox(
height: 100,
),
GestureDetector(
child: Container(
child: Text(
'长按这里弹出弹窗',
style: TextStyle(backgroundColor: Colors.amber, fontSize: 15),
key: anchorKey,// 绑定key(关键代码!!)
),
),
onLongPressStart: (detail) {
setState(() {});
_showMenu(context, detail);
},
)
],
);
}
PopupMenuButton _popMenu() {
return PopupMenuButton(
itemBuilder: (context) => _getPopupMenu(context),
onSelected: (dynamic value) {
print('onSelected$value');
_selectValueChange(value);
},
onCanceled: () {
print('取消');
setState(() {});
},
);
}
_selectValueChange(String value) {
setState(() {});
}
_showMenu(BuildContext context, LongPressStartDetails detail) {
// 获取到当前context(关键代码!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)
var renderBox = anchorKey.currentContext?.findRenderObject() as RenderBox;
// 获取到当前dom元素坐标(关键代码!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)
var offset = renderBox.globalToLocal(Offset(100, renderBox.size.height));
final position = RelativeRect.fromLTRB(
detail.globalPosition.dx, //取点击位置坐弹出x坐标
offset.dy, //取demo高度做弹出y坐标(这样弹出就不会遮挡文本)
detail.globalPosition.dx,
offset.dy);
var pop = _popMenu();
showMenu(
context: context,
items: pop.itemBuilder(context),
position: position, //弹出框位置
).then((dynamic newValue) {
if (!mounted) return null;
if (newValue == null) {
if (pop.onCanceled != null) pop.onCanceled!();
return null;
}
if (pop.onSelected != null) pop.onSelected!(newValue);
});
}
_getPopupMenu(BuildContext context) {
return [
PopupMenuItem(
value: '举报',
child: Text('举报'),
),
];
}
}
参考来源:
1.点击位置弹出菜单栏(仿微信文本长按位置下方弹出菜单)
2.Get “y” position of container on Flutter