在此小部件中,尽管按钮正确定位并且位于最顶层,但点击手势检测器失败,其预期功能是仅在动画完成后才呈现按钮并对点击事件做出反应我做了一些测试来检查是否动画可能不会结束并成为罪魁祸首,但事实并非如此,这里是包含它的小部件,还要注意按钮直接位于匹配图像上方
这是包含手势检测器的小部件
Widget buildImageWithTextAndLine(String imagePath, String text, int index) {
bool isTapped = _tappedButtons[index] ?? false; // Safeguard against null
return Column(
children: [
Stack(
children: [
Image.asset(imagePath, width: 319, height: 111.5),
// Your positioning code remains unchanged
if (_animationComplete)
Positioned(
top: buttonTopOffset,
left: buttonLeftOffset,
child: GestureDetector(
onTap: () {
setState(() {
_tappedButtons[index] = !isTapped; // Toggle the tapped state
print("Button $index tapped state: ${_tappedButtons[index]}");
});
},
child: Opacity(
opacity: buttonOpacity,
child: Container(
width: buttonWidth,
height: buttonHeight,
// Dynamically change color based on tap
color: isTapped ? Colors.red : const Color.fromARGB(255, 0, 0, 0),
),
),
),
),
],
),
SizedBox(height: widget.spaceBetweenImages),
],
);
}
这是整个上下文文件
import 'package:flutter/material.dart';
class Era extends StatefulWidget {
final double topSpacing;
final double spaceBetweenImages;
final double spaceBetweenRows;
const Era({
Key? key,
this.topSpacing = 35.0,
this.spaceBetweenImages = 8,
this.spaceBetweenRows = 60.0,
}) : super(key: key);
@override
_EraState createState() => _EraState();
}
class _EraState extends State<Era> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<Offset> _leftColumnAnimation;
late Animation<Offset> _rightColumnAnimation;
bool _animationComplete = false;
Map<int, bool> _tappedButtons = {};
// Configurable variables for line and text
final double lineWidth = 280.0;
final double lineHeight = 0.5;
final double lineTopOffset = 30.0;
final double lineLeftOffset = 10.0;
final double fontSize = 35.0;
final double textTopOffset = 25.0;
final double textLeftOffset = 10.0;
// Button customization variables
final double buttonWidth = 319.0; // You can adjust this
final double buttonHeight = 111.5; // You can adjust this
final double buttonTopOffset = 0.0; // You can adjust this
final double buttonLeftOffset = 0.0; // You can adjust this
final double buttonOpacity = 1; // Opacity of the button
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 600),
vsync: this,
);
_controller.addListener(() {
if (_controller.isCompleted) {
setState(() {
_animationComplete = true;
});
}
});
_leftColumnAnimation = Tween<Offset>(
begin: const Offset(-1.5, 0.0),
end: Offset.zero,
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeOut,
));
_rightColumnAnimation = Tween<Offset>(
begin: const Offset(1.5, 0.0),
end: Offset.zero,
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeOut,
));
_controller.forward();
// Assuming the number of images/buttons is known and fixed
int numberOfButtons = 6; // Adjust this based on your actual number of images/buttons
for (int i = 0; i < numberOfButtons; i++) {
_tappedButtons[i] = false;
}
}
Widget buildImageWithTextAndLine(String imagePath, String text, int index) {
bool isTapped = _tappedButtons[index] ?? false; // Safeguard against null
return Column(
children: [
Stack(
children: [
Image.asset(imagePath, width: 319, height: 111.5),
// Your positioning code remains unchanged
if (_animationComplete)
Positioned(
top: buttonTopOffset,
left: buttonLeftOffset,
child: GestureDetector(
onTap: () {
setState(() {
_tappedButtons[index] = !isTapped; // Toggle the tapped state
print("Button $index tapped state: ${_tappedButtons[index]}");
});
},
child: Opacity(
opacity: buttonOpacity,
child: Container(
width: buttonWidth,
height: buttonHeight,
// Dynamically change color based on tap
color: isTapped ? Colors.red : const Color.fromARGB(255, 0, 0, 0),
),
),
),
),
],
),
SizedBox(height: widget.spaceBetweenImages),
],
);
}
@override
Widget build(BuildContext context) {
return Positioned(
left: 0,
right: 0,
top: widget.topSpacing,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SlideTransition(
position: _leftColumnAnimation,
child: Column(
children: [
buildImageWithTextAndLine('assets/conquest/swedishphase.png', "The Swedish Phase 1630", 0),
buildImageWithTextAndLine('assets/conquest/frenchphase.png', "The French Phase 1635", 1),
buildImageWithTextAndLine('assets/conquest/dutchship.png', "Cuba 1628", 2),
],
),
),
SizedBox(width: widget.spaceBetweenRows),
SlideTransition(
position: _rightColumnAnimation,
child: Column(
children: [
buildImageWithTextAndLine('assets/conquest/bohemianphase.png', "The Bohemian Phase 1618", 3),
buildImageWithTextAndLine('assets/conquest/danishphase.png', "The Danish Phase 1625", 4),
buildImageWithTextAndLine('assets/conquest/brazil.png', "Brazil 1624", 5),
],
),
),
],
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
我希望找到为什么手势检测器被阻止的答案,这不是因为我测试了动画设置为 true,也不是因为手势一般不起作用,它只是在该文件中不起作用,其中按钮位于按钮上方的特定堆栈中img 这就是可能造成这个问题的原因
您能否澄清一下您运行 Flutter 应用程序的平台是什么?是 Chrome、Android 还是 iOS。我在网络上运行了该程序,但我无法收集您到底想要实现的目标。