1

I have a column of buttons on my app. The middle button needs to be animated. So basically when the user taps I need to show an animation.

enter image description here

As you can see the heart button has two parts. Anything below the heart button is fixed. Anything above the heart button is animated. So the 9 should only be visible when the actual button is tapped.

This is my code for reaction_button so far:

        Column(
          children: [
            AnimatedOpacity(
              opacity: isVisible ? 1.0 : 0.0,
              duration: const Duration(seconds: 1),
              child: AnimatedContainer(
                duration: const Duration(seconds: 1),
                curve: Curves.bounceInOut,
                child: CounterCard(count: userLikeCount),
              ),
            ),
            LikeButton(
              size: 40,
              animationDuration: const Duration(milliseconds: 500),
              likeCountAnimationDuration: const Duration(milliseconds: 10),
              bubblesColor: const BubblesColor(
                dotPrimaryColor: Colors.red,
                dotSecondaryColor: Colors.red,
              ),
              circleColor: const CircleColor(
                start: Colors.pink,
                end: Colors.pink,
              ),
              likeBuilder: (isLiked) {
                return SvgPicture.asset(
                  "assets/icons/heart.svg",
                  color: buttonColor,
                );
              },
              onTap: (isLiked) => increment(isLiked),
            ),
            Text(
              likeCount.toString(),
              style: const TextStyle(
                fontWeight: FontWeight.w400,
                color: Colors.black,
              ),
            )
          ],
        ),
  Future<bool> increment(bool isLiked) async {
    setState(() {
      likeCount++;
      userLikeCount++;
      buttonColor = Colors.pink;
    });
    if (userLikeCount >= 100) {
      userLikeCount = 100;
    }
    setState(() {
      isVisible = true;
    });
    Future.delayed(const Duration(milliseconds: 800)).then((value) {
      setState(() {
        isVisible = false;
      });
    });
    return true;
  }

For now when the user presses the button a simple CountCard is shown which disappears after 1 second. What I need to add is an up going(I dont know the word for it, FadeUp animation?). I made the disappearing part work.

thanks to @yeasin_sheikh this is what I have managed so far:

  AnimatedContainer(
     transform: animation.value,
     color: Colors.red,
     duration: controller.duration!,
     child: Visibility(
        visible: isVisible,
        child: CounterCard(count: userLikeCount),
     ),
   ),

for on tap

    controller.forward();
    setState(() {
      isVisible = true;
    });
    Future.delayed(const Duration(seconds: 1)).then((value) {
      controller.reverse();
      setState(() {
        isVisible = false;
      });
    });

and initialized:

  late final controller = AnimationController(
      vsync: this, duration: const Duration(milliseconds: 200))
    ..addListener(() {
      setState(() {});
    });
  late final animation = Tween<Matrix4>(
          begin: Matrix4.translationValues(0, 30, 0), end: Matrix4.identity())
      .animate(controller);

The result is as:

Result

All the buttons are moving which I don't like much and if the user presses the react button quickly the animation gets all fuzzy. So, any suggestions regarding those are highly appreciated.

5
  • can you include sample but full widget Commented Nov 5, 2022 at 11:24
  • I am sorry but all I have is the figma but as it's confidential I can't share it. But when the heart button is pressed a value(ex: 9/10/11) will appear and go up(very much like the fade out animation). Commented Nov 5, 2022 at 12:04
  • It's ok, the LikeButton can be switched with any button? It would be easier if could include minimal-reproducible-example Commented Nov 5, 2022 at 12:08
  • yes like button is pretty simple. Takes a call back function called onTap and the entire LikeButton is wrapped with GestureDetector. Commented Nov 5, 2022 at 12:22
  • Hey I have updated the code. I need the CountCard to go up a few pixels and disappear. Commented Nov 5, 2022 at 12:27

1 Answer 1

2

You can check this widget for basic animation, better might be using AnimationBuilder.

class TAn extends StatefulWidget {
  const TAn({super.key});

  @override
  State<TAn> createState() => _TAnState();
}

class _TAnState extends State<TAn> with SingleTickerProviderStateMixin {
  late final controller =
      AnimationController(vsync: this, duration: Duration(milliseconds: 200))
        ..addListener(() {
          setState(() {});
        });
// I was curious if Matrix4 will work or not 😅
  late final animation = Tween<Matrix4>(
          begin: Matrix4.translationValues(0, 48, 0), end: Matrix4.identity())
      .animate(controller);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            AnimatedContainer(
              transform: animation.value,
              color: Colors.red,
              duration: controller.duration!,
              child: Text("6."),
            ),
            ElevatedButton(
              onPressed: () {
                controller.forward();
              },
              child: Text("show "),
            ),
            ElevatedButton(
              onPressed: () {
                controller.reverse();
              },
              child: Text(" hide"),
            )
          ],
        ),
      ),
    );
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I have updated my code and added a sample video of the near end product

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.