Home > Mobile >  how to animate the size of the container, as contents within it change in Flutter?
how to animate the size of the container, as contents within it change in Flutter?

Time:06-18

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

initial state

Final 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

enter image description here

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(),
            ],
          ),
        ),
  • Related