Art*_*ine 11 dart flutter flutter-layout
我有这段代码是从Style clipboard in flutter 中得到的
showMenu(
context: context,
// TODO: Position dynamically based on cursor or textfield
position: RelativeRect.fromLTRB(0.0, 600.0, 300.0, 0.0),
items: [
PopupMenuItem(
child: Row(
children: <Widget>[
// TODO: Dynamic items / handle click
PopupMenuItem(
child: Text(
"Paste",
style: Theme.of(context)
.textTheme
.body2
.copyWith(color: Colors.red),
),
),
PopupMenuItem(
child: Text("Select All"),
),
],
),
),
],
);
Run Code Online (Sandbox Code Playgroud)
这段代码效果很好,除了创建的弹出窗口位于固定位置之外,我将如何使它在鼠标/按下/手指/光标位置或附近的某个位置弹出,有点像你想要的时候复制并粘贴到您的手机上。(此对话框弹出不会用于复制和粘贴)
Era*_*ore 11
我能够通过使用这个答案解决类似的问题:https : //stackoverflow.com/a/54714628/559525
基本上,我在每个 ListTile 周围添加了一个 GestureDetector(),然后你使用 onTapDown 来存储你的按下位置和 onLongPress 来调用你的 showMenu 函数。以下是我添加的关键功能:
_showPopupMenu() async {
final RenderBox overlay = Overlay.of(context).context.findRenderObject();
await showMenu(
context: context,
position: RelativeRect.fromRect(
_tapPosition & Size(40, 40), // smaller rect, the touch area
Offset.zero & overlay.size // Bigger rect, the entire screen
),
items: [
PopupMenuItem(
child: Text("Show Usage"),
),
PopupMenuItem(
child: Text("Delete"),
),
],
elevation: 8.0,
);
}
void _storePosition(TapDownDetails details) {
_tapPosition = details.globalPosition;
}
}
Run Code Online (Sandbox Code Playgroud)
然后这里是完整的代码(你必须调整一些东西,比如图像,并填写设备列表):
import 'package:flutter/material.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'dart:core';
class RecentsPage extends StatefulWidget {
RecentsPage({Key key, this.title}) : super(key: key);
final String title;
@override
_RecentsPageState createState() => _RecentsPageState();
}
class _RecentsPageState extends State<RecentsPage> {
List<String> _recents;
var _tapPosition;
@override
void initState() {
super.initState();
_tapPosition = Offset(0.0, 0.0);
getRecents().then((value) {
setState(() {
_recents = value;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFFFFFFF),
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(height: 25),
Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 40),
child: Center(
child: AutoSizeText(
"Recents",
maxLines: 1,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 32),
),
),
),
Container(
padding: EdgeInsets.only(left: 30, top: 0),
child: GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: Transform.scale(
scale: 2.0,
child: Icon(
Icons.chevron_left,
),
)),
),
],
),
Container(
height: 15,
),
Container(
height: 2,
color: Colors.blue,
),
Container(
height: 10,
),
Flexible(
child: ListView(
padding: EdgeInsets.all(15.0),
children: ListTile.divideTiles(
context: context,
tiles: _getRecentTiles(),
).toList(),
),
),
Container(height: 15),
],
),
),
),
);
}
List<Widget> _getRecentTiles() {
List<Widget> devices = List<Widget>();
String _dev;
String _owner = "John Doe";
if (_recents != null) {
for (_dev in _recents.reversed) {
if (_dev != null) {
_dev = _dev.toUpperCase().trim();
String serial = "12341234";
devices.add(GestureDetector(
onTapDown: _storePosition,
onLongPress: () {
print("long press of $serial");
_showPopupMenu();
},
child: ListTile(
contentPadding: EdgeInsets.symmetric(vertical: 20),
leading: Transform.scale(
scale: 0.8,
child: Image(
image: _myImage,
)),
title: AutoSizeText(
"$_owner",
maxLines: 1,
style: TextStyle(fontSize: 22),
),
subtitle: Text("Serial #: $serial"),
trailing: Icon(Icons.keyboard_arrow_right),
)));
}
}
} else {
devices.add(ListTile(
contentPadding: EdgeInsets.symmetric(vertical: 20),
title: AutoSizeText(
"No Recent Devices",
maxLines: 1,
style: TextStyle(fontSize: 20),
),
subtitle:
Text("Click the button to add a device"),
onTap: () {
print('add device');
},
));
}
return devices;
}
_showPopupMenu() async {
final RenderBox overlay = Overlay.of(context).context.findRenderObject();
await showMenu(
context: context,
position: RelativeRect.fromRect(
_tapPosition & Size(40, 40), // smaller rect, the touch area
Offset.zero & overlay.size // Bigger rect, the entire screen
),
items: [
PopupMenuItem(
child: Text("Show Usage"),
),
PopupMenuItem(
child: Text("Delete"),
),
],
elevation: 8.0,
);
}
void _storePosition(TapDownDetails details) {
_tapPosition = details.globalPosition;
}
}
Run Code Online (Sandbox Code Playgroud)
像这样使用手势检测器的 onTapDown
GestureDetector(
onTapDown: (TapDownDetails details) {
showPopUpMenu(details.globalPosition);
},
Run Code Online (Sandbox Code Playgroud)
然后在这个方法中我们使用点击详细信息来查找位置
Future<void> showPopUpMenu(Offset globalPosition) async {
double left = globalPosition.dx;
double top = globalPosition.dy;
await showMenu(
color: Colors.white,
//add your color
context: context,
position: RelativeRect.fromLTRB(left, top, 0, 0),
items: [
PopupMenuItem(
value: 1,
child: Padding(
padding: const EdgeInsets.only(left: 0, right: 40),
child: Row(
children: [
Icon(Icons.mail_outline),
SizedBox(
width: 10,
),
Text(
"Menu 1",
style: TextStyle(color: Colors.black),
),
],
),
),
),
PopupMenuItem(
value: 2,
child: Padding(
padding: const EdgeInsets.only(left: 0, right: 40),
child: Row(
children: [
Icon(Icons.vpn_key),
SizedBox(
width: 10,
),
Text(
"Menu 2",
style: TextStyle(color: Colors.black),
),
],
),
),
),
PopupMenuItem(
value: 3,
child: Row(
children: [
Icon(Icons.power_settings_new_sharp),
SizedBox(
width: 10,
),
Text(
"Menu 3",
style: TextStyle(color: Colors.black),
),
],
),
),
],
elevation: 8.0,
).then((value) {
print(value);
if (value == 1) {
//do your task here for menu 1
}
if (value == 2) {
//do your task here for menu 2
}
if (value == 3) {
//do your task here for menu 3
}
});
Run Code Online (Sandbox Code Playgroud)
希望它有效
| 归档时间: |
|
| 查看次数: |
7729 次 |
| 最近记录: |