Flutter 颤振打开列表项上方的弹出菜单
我正在用Firestore制作一个Flitter聊天应用程序,但我被其中一个要求难住了:在聊天对话框上方显示一个反应菜单。我需要的是,当用户长按聊天文本时,反应菜单将出现在当前聊天位置的上方。类似于Facebook Messenger应用程序:Flutter 颤振打开列表项上方的弹出菜单,flutter,dart,flutter-plugin,Flutter,Dart,Flutter Plugin,我正在用Firestore制作一个Flitter聊天应用程序,但我被其中一个要求难住了:在聊天对话框上方显示一个反应菜单。我需要的是,当用户长按聊天文本时,反应菜单将出现在当前聊天位置的上方。类似于Facebook Messenger应用程序: 我环顾四周,发现它似乎太多了,仅仅是一个简单的功能(使弹出菜单出现在列表平铺上方,不需要动画)。我还发现了这个包:,但它不允许将小部件包装在另一个小部件上以打开reacton菜单。有没有一种简单的方法可以存档?我已经查看了PopupMenuButton
我环顾四周,发现它似乎太多了,仅仅是一个简单的功能(使弹出菜单出现在列表平铺上方,不需要动画)。我还发现了这个包:,但它不允许将小部件包装在另一个小部件上以打开reacton菜单。有没有一种简单的方法可以存档?我已经查看了PopupMenuButton,但它只允许按ON键,不允许长按。您可以使用
覆盖
小部件。我给你举个简单的例子
import 'package:flutter/material.dart';
class Temp extends StatefulWidget {
@override
_TempState createState() => _TempState();
}
class _TempState extends State<Temp> {
GlobalKey floatingKey = LabeledGlobalKey("Floating");
bool isFloatingOpen = false;
OverlayEntry floating;
OverlayEntry createFloating() {
RenderBox renderBox = floatingKey.currentContext.findRenderObject();
Offset offset = renderBox.localToGlobal(Offset.zero);
return OverlayEntry(
builder: (context) {
return Positioned(
left: offset.dx,
width: renderBox.size.width,
top: offset.dy - 50,
child: Material(
elevation: 20,
child: Container(
height: 50,
color: Colors.blue,
child: Text("I'm floating overlay")
)
)
);
}
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
key: floatingKey,
color: Colors.red,
onPressed: (){
setState(() {
if(isFloatingOpen) floating.remove();
else {
floating = createFloating();
Overlay.of(context).insert(floating);
}
isFloatingOpen = !isFloatingOpen;
});
},
)
),
);
}
}
导入“包装:颤振/材料.省道”;
类Temp扩展StatefulWidget{
@凌驾
_TempState createState()=>u TempState();
}
类_TempState扩展了状态{
GlobalKey floatingKey=LabeledGlobalKey(“浮动”);
bool isFloatingOpen=false;
上入口浮动;
OverlayEntry createFloating(){
RenderBox RenderBox=floatingKey.currentContext.finderObject();
Offset Offset=renderBox.localToGlobal(Offset.zero);
返回重叠入口(
生成器:(上下文){
返回定位(
左:offset.dx,
宽度:renderBox.size.width,
顶部:offset.dy-50,
儿童:材料(
海拔:20,
子:容器(
身高:50,
颜色:颜色,蓝色,
子:文本(“我在浮动覆盖”)
)
)
);
}
);
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
孩子:升起按钮(
键:floatingKey,
颜色:颜色,红色,
已按下:(){
设置状态(){
如果(isFloatingOpen)浮动。删除();
否则{
floating=createFloating();
覆盖.of(上下文).插入(浮动);
}
isFloatingOpen=!isFloatingOpen;
});
},
)
),
);
}
}
我认为在这个布局上最好使用覆盖小部件:````谢谢你的建议,我尝试了你的例子,它与我正在寻找的非常相似。一个问题是,是否有一种方法可以在按下outside键时关闭覆盖,而不仅仅是在单击按钮时关闭覆盖?这对于ListView又是如何工作的?isFloatingOpen
只是管理覆盖层打开和关闭状态的一个变量。您可以使用GestureDetector包装整个脚手架,并在覆盖层打开时使用onTap关闭覆盖层。是的,它可以与ListView一起工作,我以前试过。顺便说一句,如果我的答案有用的话,可以用upvote吗?抱歉,我正在尝试收集声誉hahaSo如何为每个列表项分配浮动键?假设我有一个来自数据源的100个项目的列表,并使用ListView.builder将其构建到ListView中,我是否必须创建100个不同的floatingKey
来分配给每个ListItem?您可以为数据创建模型类,以便每个数据都有自己的键。