I want to create an animated button, which has a sync icon initially when user taps on it, it will also contain a text "Cancel" and the sync icon starts spinning.
Initial state
Final state
This is widget i am using for button. I know this can be done by adding transition property in CSS, i tried using ScaleTransition in Flutter, but still the container expands abruptly (as ScaleTransition itself takes up all the size in beginning itself).
AnimatedContainer(
duration: Duration(milliseconds: 3000),
padding: const EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
border: Border.all(
color: Colors.pink.withOpacity(0.6),
),
borderRadius: BorderRadius.circular(5.0),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
RotationTransition(
turns: Tween(begin: 0.0, end: 1.0)
.animate(_rotationAnimationController),
child: const Icon(
Icons.sync,
color: Colors.pink,
),
),
ScaleTransition(
scale: _scaleAnimationController,
child: (state is NoteSyncOnGoing)
? Row(
children: const [
SizedBox(width: 5),
Text(
"Cancel",
style: TextStyle(
color: Colors.pink,
fontWeight: FontWeight.w600,
),
),
SizedBox(width: 5),
],
)
: const SizedBox.shrink(),
),
],
),
),
EDIT
Checking the state before ScaleTransition doesn't solve the issue as well, because when ScaleTransition is mounted, the ScaleTransition widget itself acquires the maximum space acquired by its child after the scaling animation is completed.
So it will result in something like this
And then Cancel text appears by scaling animation
CodePudding user response:
AnimatedContainer doesn't give you size animation, you have to use AnimatedSize, And remove ScaleTransition.
AnimatedSize(
duration: const Duration(milliseconds: 3000),
child: Container(
padding: const EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
border: Border.all(
color: Colors.pink.withOpacity(0.6),
),
borderRadius: BorderRadius.circular(5.0),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
RotationTransition(
turns: Tween(begin: 0.0, end: 1.0)
.animate(_rotationAnimationController),
child: const Icon(
Icons.sync,
color: Colors.pink,
),
),
(state is NoteSyncOnGoing)
? Row(
children: const [
SizedBox(width: 5),
Text(
"Cancel",
style: TextStyle(
color: Colors.pink,
fontWeight: FontWeight.w600,
),
),
SizedBox(width: 5),
],
)
: const SizedBox.shrink(),
],
),
),
)
CodePudding user response:
Instead of checking the state inside scale transition check it before the scale transition widget
AnimatedContainer(
duration: Duration(milliseconds: 3000),
padding: const EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
border: Border.all(
color: Colors.pink.withOpacity(0.6),
),
borderRadius: BorderRadius.circular(5.0),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
RotationTransition(
turns: Tween(begin: 0.0, end: 1.0)
.animate(_rotationAnimationController),
child: const Icon(
Icons.sync,
color: Colors.pink,
),
),
(state is NoteSyncOnGoing)? ScaleTransition(
scale: _scaleAnimationController,
child: Row(
children: const [
SizedBox(width: 5),
Text(
"Cancel",
style: TextStyle(
color: Colors.pink,
fontWeight: FontWeight.w600,
),
),
SizedBox(width: 5),
],
)
):SizedBox.shrink(),
],
),
),