gpt4 book ai didi

dart - Flutter:实现 peek & pop 效果

转载 作者:IT王子 更新时间:2023-10-29 07:06:32 28 4
gpt4 key购买 nike

我试图实现一种 peek & pop 效果 - 当用户点击并按住一张卡片时,一个对话框打开,当用户不再点击并按住屏幕时关闭:

Listener(
onPointerDown: (PointerDownEvent e) {
// open dialog
showDialog(
context: context,
builder: (context) => Container(
child: Card(),
));
},
onPointerUp: (PointerUpEvent e) {
// dismiss dialog
if (Navigator.of(context).canPop()) {
Navigator.of(context).pop('dialog');
}
},
child: Card()
)

它工作得很好,当我按住卡片时显示对话框,当我不再按住时关闭。

但我想在调用 onPointerDown 之前有一些延迟,例如 GestureDectector 中的 onLongPress - 当我长按时我能够让对话框显示,但是当我离开屏幕时从未调用 onTapUp:

GestureDetector(
onLongPress: () {
// open dialog
showDialog(
context: context,
builder: (context) => Container(child: Card()));
},
onTapUp: (TapUpDetails d) {
// dismiss dialog
if (Navigator.of(context).canPop()) {
Navigator.of(context).pop();
}
},
child: Card()
)

我尝试通过以下方式进行操作,但也从未调用过 onTapUp:

  GestureDetector(
onTapDown: (TapDownDetails d) {
// open dialog
showDialog(context: context, builder: (context) => Card());
},
onTapUp: (TapUpDetails d) {
// dismiss dialog
if (Navigator.of(context).canPop()) {
Navigator.of(context).pop();
}
},
child: Card())

但以下显示水龙头正确注册:

GestureDetector(
onTapDown: (TapDownDetails d) {
print("down")
},
onTapUp: (TapUpDetails d) {
print("up")
},
child: Card()
)

环顾四周后,我注意到了这个 flutter PR它添加了 onLongPressUp - 我将这些更改添加到我的 flutter 中,然后尝试像这样重新实现我以前的代码:

GestureDetector(
onLongPress: () {
// open dialog
showDialog(
context: context,
builder: (context) => Container(child: Card()));
},
onLongPressUp: () {
// dismiss dialog
if (Navigator.of(context).canPop()) {
Navigator.of(context).pop();
}
},
child: Card()
)

对话框在长按时出现,但当我不再长按时从未被关闭 - onLongPressUp 似乎没有被调用,但以下显示它正在正确注册我的点击:

GestureDetector(
onLongPress: () {
print("longpress")
},
onLongPressUp: () {
print("longpressup")
},
child: Card()
)

在所有这些中,仅使用 Listener,我能够通过点击向下和向上点击来打开和关闭对话框,但我想在调用 onPointerDown 之前添加一个延迟,我还尝试在 onPointerDown 中添加一个计时器但似乎不起作用。

有什么解决办法吗?

最佳答案

这是一个使用 StatefulWidgetStack 而不是 Navigator 的解决方案。

我在使用您的代码时遇到的问题是,当您使用 showDialog 打开对话框时,Listener 不再接收指针事件,因此最好将所有内容都放在一个单个顶级小部件。

我还使用了一个 Timer,它会在指针上升或用户离开页面时取消。

import 'dart:async';

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(),
);
}
}

class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
Timer _showDialogTimer;
bool _dialogVisible = false;

@override
void dispose() {
_showDialogTimer?.cancel();
super.dispose();
}

void _onPointerDown(PointerDownEvent event) {
_showDialogTimer = Timer(Duration(seconds: 1), _showDialog);
}

void _onPointerUp(PointerUpEvent event) {
_showDialogTimer?.cancel();
_showDialogTimer = null;
setState(() {
_dialogVisible = false;
});
}

void _showDialog() {
setState(() {
_dialogVisible = true;
});
}

@override
Widget build(BuildContext context) {
final layers = <Widget>[];

layers.add(_buildPage());

if(_dialogVisible) {
layers.add(_buildDialog());
}

return Listener(
onPointerDown: _onPointerDown,
onPointerUp: _onPointerUp,
child: Stack(
fit: StackFit.expand,
children: layers,
),
);
}

Widget _buildPage() {
return Scaffold(
appBar: AppBar(
title: Text('Example App'),
),
body: Center(
child: Text('Press me'),
),
);
}

Widget _buildDialog() {
return Container(
color: Colors.black.withOpacity(0.5),
padding: EdgeInsets.all(50.0),
child: Card(),
);
}
}

关于dart - Flutter:实现 peek & pop 效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51480827/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com