我有两个容器,两个容器都有GestureDetector。第一个容器的OnTap可以正常工作,但不能与另一个容器一起使用。 第一个容器是图像,第二个容器是部分在第一个容器上对齐的绿色背景。
new Stack(
alignment: Alignment(0.0, 1.44),
children: <Widget>[
GestureDetector(
onTap: () => _openImage(context),
child: Container(
width: 340.0,
foregroundDecoration: new BoxDecoration(
color: Color.fromRGBO(155, 85, 250, 0.55)),
height: 240.0,
child: FadeInImage.assetNetwork(
placeholder: 'assets/dimlight.png',
image: post.imageUrl,
fit: BoxFit.cover,
),
),
),
new GestureDetector(
child: new Container(
color: Colors.green,
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
SizedBox(width: 7.0),
CircleAvatar(
backgroundImage:
new AssetImage("assets/boy.png")
radius: 30.0,
),
SizedBox(
width: 7.0,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new SizedBox(
height: 20.0,
),
Text(
post.user.name,
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(
getTimeString(post.timestamp.toString()),
style: TextStyle(
color: Colors.grey, fontSize: 10.0),
),
],
),
SizedBox(
width: 20.0,
),
],
),
),
onTap: () => _navigateToDetails(context),
)
],
)
布局截图
答案 0 :(得分:2)
尝试将behavior
的{{1}}属性设置为GestureDetector
。
答案 1 :(得分:2)
就我而言,我在堆栈中有一个CustomPainter。在我给CustomerPainter设置尺寸之前,以上所有操作均无效。显示时未明确指定大小,但未触发点击事件:
Container(
child: CustomPaint(
size: Size(30, 30),
painter: RecordingButton(30),
))
答案 2 :(得分:1)
您应该尝试使用 AbsorbPointer 包装您的 Container。
答案 3 :(得分:0)
我认为您的小部件彼此重叠,并且导致了问题。您可以通过用容器包装GestureDetector进行检查,并提供颜色以获得更好的理解。
您的代码还不够,这就是为什么我添加以下示例可以帮助您更清楚地理解。
在示例中交换GestureDetector的位置,您会发现在第一种情况下它仅打印第二个,在其他情况下,如果单击上面的部分,它将首先打印到。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Firebase Auth Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Card(
margin: EdgeInsets.all(40.0),
child: new Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
GestureDetector(
onTap: () => print("first container"),
child: Container(
width: 340.0,
foregroundDecoration: new BoxDecoration(
color: Color.fromRGBO(155, 85, 250, 0.0)),
height: 240.0,
child: FadeInImage.assetNetwork(
placeholder: 'images/p1.png',
image:
"https://www.straitstimes.com/sites/default/files/styles/article_pictrure_780x520_/public/articles/2016/06/15/ST_20160615_LLIMH_2368135.jpg?itok=8Dggu2PM×tamp=1465926004",
fit: BoxFit.cover,
),
),
),
new GestureDetector(
child: new Container(
foregroundDecoration: BoxDecoration(
color: Color.fromRGBO(155, 85, 250, 0.4)),
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
SizedBox(width: 7.0),
CircleAvatar(
backgroundImage: new AssetImage("images/p2.jpg"),
radius: 30.0,
),
SizedBox(
width: 7.0,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new SizedBox(
height: 20.0,
),
Text(
"sfvgefbv",
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(
"sfvmsfkv",
style: TextStyle(
color: Colors.grey, fontSize: 10.0),
),
],
),
),
new Container(
alignment: AlignmentDirectional.centerEnd,
// todo add here check if not logged in then ask to
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
IconButton(
icon: Icon(
Icons.comment,
color: Colors.green,
),
onPressed: () => print("message click")),
Text(
"2",
style: TextStyle(
color: Colors.green,
),
),
SizedBox(
width: 10.0,
)
],
),
),
],
),
),
onTap: () => print("this is second container"),
),
new Expanded(
child: Container(
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
Text(
"fsvkmfskbnmkffvberk",
style: TextStyle(
color: Colors.green, fontWeight: FontWeight.bold),
),
new Text(
"svklmfslkbnernkjrnvkrwjnvrw",
maxLines: 6,
overflow: TextOverflow.ellipsis,
),
],
),
),
),
],
),
),
);
}
}
答案 4 :(得分:0)
我看到您正在调用回调方法,而不是将其分配给GestureDetector小部件的onTap属性。传递方法名称,不要在此处调用。
答案 5 :(得分:0)
使用InkWell
代替GestureDetector
解决了我的问题。
答案 6 :(得分:0)
对于其他来此帖子的人,可能导致此问题的另一件事是层次结构更高的AbsorbPointer。
答案 7 :(得分:0)
好的,这对我来说很愚蠢,但是由于它可能发生在我们当中,所以我将解释:
我的构建上下文(为示例简化)树是这样的:
Widget build(BuildContext context) {
return (...) (
child: GestureDetector(
onTap: () => _myFunction(),
child: Container(
height: 64.0,
width: 128.0,
child: (...)
似乎合法吗?但是后来我检查了树的底部更多细节:
(...)
onTap: () => _myFunction(),
child: Container(
height: 64.0,
width: 128.0,
child: TheSourceOfEvil() // <-- whoopsie!
快速检查了TheSourceOfEvil,以发现罪魁祸首实际上是另一个OTHER GestureDetector 有一个孩子,我还没有实施onTap: () => {},
:
Widget TheSourceOfEvil( {
return (...) (
child: GestureDetector(
onTap: () => {}, // override previous GestureDetector
child: Container(
child: (...);
摆脱了它,它立即解决了我令人困惑的问题。希望对您有所帮助!
答案 8 :(得分:0)
GestureDetector在其块内编写代码时不起作用 将无法正常工作
GestureDetector(
onTap: () {
setState(() {
_color = Colors.red;
});
},),
您将这样写,它将起作用
GestureDetector(
onTap: () {
changed();
},),
方法
void changed() {
setState(() {
_color = Colors.red;
});}
答案 9 :(得分:0)
对我来说,这是一个问题,其中Stack
以外的其他项目在clipBehavior: Clip.none
之外溢出。
在这种情况下,该项目可见但不可触摸。因此,我更新了布局以删除clipBehavior: Clip.none
上的Stack
,GestureDetector
开始工作。 ?
答案 10 :(得分:0)
如果您正在使用 GoogleMap 小部件并想要添加搜索字段/文本字段,您应该意识到地图小部件正在消耗您的手势。我做这样的事情:
final FocusNode _focusNode = new FocusNode();
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
print("tap");
if (_focusNode.hasPrimaryFocus) {
_focusNode.unfocus();
rebuildAfterFocusChange();
}
},
child: Stack(children: [
AbsorbPointer(absorbing: _focusNode.hasPrimaryFocus, child: StoreMapView()),
showSearchField(model),
]),
);
}
Widget showSearchField(StoreFinderViewModel model) {
return SafeArea(
child: Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: 12.0),
child: TextField(
onTap: () {
rebuildAfterFocusChange();
},
onSubmitted: (String input) {
rebuildAfterFocusChange();
// do other stuff
});
},
focusNode: _focusNode,
),
),
);
}
void rebuildAfterFocusChange() {
setState(() {});
}
我正在使用 AbsorbPointer 小部件来吸收点击/点击,但前提是我的文本字段具有焦点。我打电话给我的 rebuildAfterFocusChange();如果我点击我的“搜索字段”,请使用文本字段的 onsubmit 方法在我的后端触发搜索,并在我取消对我的文本字段的关注之后。
答案 11 :(得分:0)
还要考虑 Listener
小部件。它帮助了我。
https://api.flutter.dev/flutter/widgets/Listener-class.html
示例:
Listener(
onPointerDown: (_) {}, // onTapDown
onPointerUp: (_) => {}, // onTapUp
child: Container(),
)
答案 12 :(得分:-1)
由于stack
。widget
上有GestureDetector
。
解决方案:
Stack(
children: <Widget>[
...//Other widgets,
GestureDetector()
]