How to create a like button with animation in flutter

We’ll create a custom animated like button that changes color and size when pressed.

steps:

  1. We added with SingleTickerProviderStateMixin to the _NormalPageState class to enable animation capabilities.
  2. We introduced new variables for the animation:_controller: AnimationController to manage the animation._colorAnimation: Animation for changing the color of the like button._sizeAnimation: Animation for changing the size of the like button.isLiked: Boolean to track the liked state.
  3. In the initState method, we set up the animations:Created the AnimationController with a duration of 300 milliseconds.Set up the _colorAnimation to transition from grey to red.Created a _sizeAnimation that grows the icon and then shrinks it back to its original size.Added a listener to update the isLiked state based on the animation status.
  4. The AnimatedBuilder creates an IconButton with a heart icon (Icons.favorite). The color and size of this icon are controlled by our animations.

FULL CODE:

import 'package:flutter/material.dart';

class NormalPage extends StatefulWidget {
  const NormalPage({Key? key}) : super(key: key);

  @override
  State<NormalPage> createState() => _NormalPageState();
}

class _NormalPageState extends State<NormalPage> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Color?> _colorAnimation;
  late Animation<double> _sizeAnimation;
  bool isLiked = false;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(milliseconds: 300),
      vsync: this,
    );

    _colorAnimation = ColorTween(
      begin: Colors.grey[400],
      end: Colors.red,
    ).animate(_controller);

    _sizeAnimation = TweenSequence<double>([
      TweenSequenceItem(tween: Tween<double>(begin: 80, end: 100), weight: 50),
      TweenSequenceItem(tween: Tween<double>(begin: 100, end: 80), weight: 50),
    ]).animate(_controller);

    _controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        setState(() {
          isLiked = true;
        });
      }
      if (status == AnimationStatus.dismissed) {
        setState(() {
          isLiked = false;
        });
      }
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("This is a title"),
        leading: IconButton(
          icon: const Icon(Icons.menu),
          onPressed: () {},
        ),
        actions: <Widget>[
          IconButton(
            icon: const Icon(Icons.comment),
            onPressed: () {},
          ),
          IconButton(
            icon: const Icon(Icons.settings),
            onPressed: () {},
          ),
        ],
        elevation: 1,
      ),
      body: Material(
        child: SafeArea(
          child: Center(
            child: AnimatedBuilder(
              animation: _controller,
              builder: (BuildContext context, _) {
                return GestureDetector(
                  onTap: () {
                    isLiked ? _controller.reverse() : _controller.forward();
                  },
                  child: Icon(
                    Icons.favorite,
                    color: _colorAnimation.value,
                    size: _sizeAnimation.value,
                  ),
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注