如何检测用户点击堆栈中的小部件顶部以将其从 onTap 函数中删除?
我有小部件列表,树结构是定位的(给顶部、右侧、底部随机值)->Transfor.rotate->Align->container
。此列表位于 GestureDetector->Stack
onTap: () {
setState(() {
stackList.removeLast();
});
}
我可以从堆栈中删除顶部的小部件,但我如何才能找到用户只点击了堆栈中的顶部小部件?
在 initState 中,生成 20 个 Positioned 小部件并存储在列表中,并将该列表作为子级传递到堆栈中给 gestureDetector,如下所示
下面是Scaffold home statefulclass:
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
print('tapped!');
setState(() { //Here somehow need to find user tapped on top widget on stack or not
stackList.removeLast();
});
},
child: Stack(
children: <Widget>[
...stackList,
],
),
);
}
最佳答案
您必须对小部件的组成方式进行一些修改。我设法使用以下树结构让它工作
Positioned -> Transform.rotate -> Align -> GestureDetector -> Container
我创建了一个 Widget 来保存这个 Widget 树
class TappablePositionedWidget extends StatelessWidget {
final Container child;
final double bottom;
final double right;
final double top;
final double angle;
final VoidCallback onTap;
final AlignmentGeometry alignment;
TappablePositionedWidget({
this.angle,
this.onTap,
this.bottom,
this.child,
this.right,
this.top,
this.alignment,
}) {
assert(alignment != null);
}
@override
Widget build(BuildContext context) {
return Positioned(
top: top,
right: right,
bottom: bottom,
child: Transform.rotate(
angle: angle,
child: Align(
alignment: alignment,
child: GestureDetector(
onTap: onTap,
child: child,
),
),
),
);
}
}
然后用这个小部件的实例填充堆栈列表。
List<TappablePositionedWidget> stackList = [
TappablePositionedWidget(
bottom: Random().nextInt(200).toDouble(),
top: Random().nextInt(200).toDouble(),
right: Random().nextInt(200).toDouble(),
angle: Random().nextInt(360).toDouble(),
alignment: randomAlignment,
child: Container(
height: 240,
width: 250,
color: Colors.red,
),
),
.
.
.
]
生成随机比对的代码
static AlignmentGeometry get randomAlignment {
int index = Random().nextInt(9);
switch (index) {
case 0:
return Alignment.centerLeft;
break;
case 1:
return Alignment.centerRight;
break;
case 2:
return Alignment.center;
break;
case 3:
return Alignment.bottomCenter;
break;
case 4:
return Alignment.topCenter;
break;
case 5:
return Alignment.bottomLeft;
break;
case 6:
return Alignment.bottomRight;
break;
case 7:
return Alignment.topLeft;
break;
case 8:
return Alignment.topRight;
break;
default:
return Alignment.center;
break;
}
}
最后填充堆栈
Stack(
children: stackList.map((widget) {
if (stackList.indexOf(widget) == stackList.length - 1) {
return TappablePositionedWidget(
onTap: () {
setState(() {
stackList.removeLast();
});
},
right: widget.right,
angle: widget.angle,
top: widget.top,
bottom: widget.bottom,
child: widget.child,
alignment: widget.alignment,
);
}
return widget;
}).toList(),
)
编辑
要初始化 stackList
添加此代码
@override
void initState() {
super.initState();
for (int i = 0; i < 10; i += 1) {
stackList.add(TappablePositionedWidget(
bottom: Random().nextInt(200).toDouble(),
top: Random().nextInt(200).toDouble(),
right: Random().nextInt(200).toDouble(),
angle: Random().nextInt(360).toDouble(),
alignment: randomAlignment,
child: Container(
height: 240,
width: 250,
color: Colors.red,
),
));
}
}
关于flutter - 如果用户在 flutter 中点击它,如何只从堆栈中删除顶部小部件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56268305/