I am having troubles with this animation. I want the orange container from below left to have an onTap to redirect to another screen. But, after the animation is finished, the onTap doesn't work. The cyan color is to display the initial position of the container. I've seen this issue before but I couldn't find an exact answer to this. Thank you! Initial form After animation
import 'package:flutter/material.dart';
import 'package:flutter_app/ui/screens/ryke_p2p_payments/animated_payment_widget_card_controller.dart';
import 'package:flutter_app/ui/screens/ryke_p2p_payments/payments_controller.dart';
import 'package:flutter_app/ui/screens/ryke_p2p_payments/request_payment/request_payment_screen.dart';
import 'package:flutter_app/utils/constants/colors.dart';
import 'package:flutter_app/utils/constants/images.dart';
import 'package:flutter_app/utils/constants/styles.dart';
import 'package:animated_widgets/animated_widgets.dart';
import 'package:get/get.dart';
class AnimatedPaymentCard extends StatefulWidget {
final String title;
final String icon;
final AnimationController animationController;
final AnimationController textAnimationController;
final AnimatedPaymentWidgetCardController cardController;
AnimatedPaymentCard({
required this.title,
required this.icon,
required this.animationController,
required this.textAnimationController,
required this.cardController,
});
@override
State<AnimatedPaymentCard> createState() => _AnimatedPaymentCardState();
}
class _AnimatedPaymentCardState extends State<AnimatedPaymentCard> {
late Animation animationUp;
late Animation widthAnimation;
late Animation heightAnimation;
late Animation<double> opacityAnimation;
late Animation imageAnimationUp;
late Animation rightAnimation;
late Animation leftAnimation;
late Animation downAnimation;
final PaymentController paymentsController = Get.find();
@override
void initState() {
opacityAnimation = Tween<double>(begin: 1.0, end: 0.0).animate(
widget.textAnimationController,
);
animationUp = Tween<double>(begin: 0, end: -30).animate(
CurvedAnimation(
parent: widget.animationController,
curve: Curves.easeInOut,
),
);
imageAnimationUp = Tween<double>(begin: 0, end: -8).animate(
CurvedAnimation(
parent: widget.animationController,
curve: Curves.easeInOut,
),
);
widthAnimation = Tween<double>(begin: 200, end: 140).animate(
CurvedAnimation(
parent: widget.animationController,
curve: Curves.easeInOut,
),
);
heightAnimation = Tween<double>(begin: 179, end: 140).animate(
CurvedAnimation(
parent: widget.animationController,
curve: Curves.easeInOut,
),
);
rightAnimation = Tween<double>(begin: 0, end: -85).animate(
CurvedAnimation(
parent: widget.animationController,
curve: Curves.easeInOut,
),
);
leftAnimation = Tween<double>(begin: 0, end: 85).animate(
CurvedAnimation(
parent: widget.animationController,
curve: Curves.easeInOut,
),
);
downAnimation = Tween<double>(begin: 0, end: 60).animate(
CurvedAnimation(
parent: widget.animationController,
curve: Curves.easeInOut,
),
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Stack(
alignment: Alignment.topCenter,
children: [
AnimatedBuilder(
builder: (context, _) {
return Transform.translate(
offset: Offset(
0,
animationUp.value,
),
child: GestureDetector(
onTap: () {
widget.textAnimationController.forward();
widget.animationController.forward();
widget.cardController.leftAnim.value = 30;
widget.cardController.downAnim.value = 30;
},
child: Container(
height: heightAnimation.value,
width: widthAnimation.value,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(
8.0,
),
),
boxShadow: [
BoxShadow(
color: Color(0xFFe6e6e6),
spreadRadius: 1,
blurRadius: 2,
offset: Offset(0, 0),
),
],
),
child: Padding(
padding: const EdgeInsets.only(
top: 16.0,
),
child: Center(
child: Transform.translate(
offset: Offset(
0,
imageAnimationUp.value,
),
child: Image.asset(
widget.icon,
width: 80,
height: 80,
),
),
),
),
),
),
);
},
animation: widget.animationController,
),
Positioned(
bottom: 10,
child: AnimatedBuilder(
builder: (context, _) {
return Container(
child: Transform.translate(
offset: Offset(leftAnimation.value, downAnimation.value),
child: GestureDetector(
onTap: () => Get.to(
() => RequestPaymentScreen(),
),
child: Container(
height: 53.0,
width: 130.0,
decoration: BoxDecoration(
color: kRykeOrange,
borderRadius: BorderRadius.all(
Radius.circular(
6.0,
),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
kPayIcon,
height: 31,
width: 31,
),
SizedBox(
width: 3,
),
Text(
'Platește',
textAlign: TextAlign.center,
style: kButtonAnimationsTextStyle,
),
],
),
),
),
),
);
},
animation: widget.animationController,
),
),
Positioned(
bottom: 10,
child: Container(
color: Colors.cyan,
child: AnimatedBuilder(
animation: widget.animationController,
builder: (BuildContext context, Widget? widget) {
return Transform.translate(
transformHitTests: false,
offset: Offset(
rightAnimation.value,
downAnimation.value,
),
child: widget,
);
},
child: GestureDetector(
onTap: () => Get.to(
() => RequestPaymentScreen(),
),
//behavior: HitTestBehavior.opaque,
child: Container(
height: 53.0,
width: 130.0,
decoration: BoxDecoration(
color: kRykeOrange,
borderRadius: BorderRadius.all(
Radius.circular(
6.0,
),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
kReceiveIcon,
height: 31,
width: 31,
),
SizedBox(
width: 3,
),
Text(
'Solicită',
textAlign: TextAlign.center,
style: kButtonAnimationsTextStyle,
),
],
),
),
),
),
),
),
AnimatedBuilder(
animation: widget.textAnimationController,
builder: (context, child) {
return Opacity(
opacity: opacityAnimation.value,
alwaysIncludeSemantics: true,
child: Padding(
padding: const EdgeInsets.only(top: 16.0),
child: GestureDetector(
onTap: () {
widget.textAnimationController.forward();
widget.animationController.forward();
},
child: Text(
widget.title,
style: kSettingsLabelsTextStyle,
maxLines: 2,
textAlign: TextAlign.center,
),
),
),
);
},
),
],
);
}
}