Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Sugestão] Separei a animação em um mixin

Utilizei um mixin para separar a minha tela do meu AnimationController, a fim de deixar o meu Widget mais "limpo" e permitir a reutilização dele em outras telas.

Inicialmente, criei um mixin:

import 'package:flutter/material.dart';

mixin ScaleAnimationMixin<T extends StatefulWidget> on State<T> {
  late AnimationController animationController;
  late Animation<double> scaleAnimation;

  TickerProvider get tickerProvider => this as TickerProvider;

  @override
  void initState() {
    super.initState();

    animationController = AnimationController(
      vsync: tickerProvider,
      duration: const Duration(
        milliseconds: 1500,
      ),
    )..repeat(
        reverse: true,
      );

    final CurvedAnimation curvedAnimation = CurvedAnimation(
      parent: animationController,
      curve: Curves.easeInOutSine,
    );

    scaleAnimation = Tween<double>(
      begin: 0.8,
      end: 1,
    ).animate(
      curvedAnimation,
    );
  }

  @override
  void dispose() {
    animationController.dispose();

    super.dispose();
  }
}

Depois eu apenas importei ele e o SingleTickerProviderStateMixin no State do meu StatefulWidget. O SingleTickerProviderStateMixin serve para que tenha acesso ao this do vsync no AnimationController. Para usar a animação, no campo scale do ScaleTransition passei o scaleAnimation do mixin:

class _CategoryComponentState extends State<CategoryComponent>
    with ScaleAnimationMixin, SingleTickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Expanded(
          child: Container(
            width: 160,
            height: 155,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(20),
              border: Border.all(
                color: ThemeColors.iconColor,
                width: 3,
              ),
              boxShadow: const [
                BoxShadow(
                  color: Color.fromARGB(29, 3, 101, 140),
                  offset: Offset(-5, -5),
                  spreadRadius: 5,
                  blurRadius: 5,
                ),
                BoxShadow(
                  color: Color.fromARGB(29, 3, 101, 140),
                  offset: Offset(5, 5),
                  spreadRadius: 5,
                  blurRadius: 5,
                )
              ],
            ),
            child: Ink(
              child: InkWell(
                borderRadius: BorderRadius.circular(15),
                onTap: () {
                  context.read<HomeCubit>().changeSelectedCategory(
                        category: widget.category,
                      );

                  Navigator.of(context).pushNamed(
                    RoutesEnum.entries.route,
                    arguments: {
                      'isFavorite': false,
                    },
                  );
                },
                child: widget.isHighlight
                    ? ScaleTransition(
                        scale: scaleAnimation,
                        child: Center(
                          child: Image.asset(
                            '${CategoriesConsts.imagePath}${widget.category.name}.png',
                            height: 80,
                            fit: BoxFit.fitHeight,
                          ),
                        ),
                      )
                    : Center(
                        child: Image.asset(
                          '${CategoriesConsts.imagePath}${widget.category.name}.png',
                          height: 80,
                          fit: BoxFit.fitHeight,
                        ),
                      ),
              ),
            ),
          ),
        ),
        Padding(
          padding: const EdgeInsets.only(
            top: 8,
          ),
          child: Text(
            widget.category.text,
            style: Theme.of(context).textTheme.titleSmall,
          ),
        ),
      ],
    );
  }
}
1 resposta
solução!

Oi, Cleiton! Como vai?

Obrigada por compartilhar seu código com a comunidade Alura.

Gostei da forma como você separou a animação utilizando o mixin para manter o código mais limpo e reutilizável. Isso facilita bastante a manutenção e a expansão do seu aplicativo. E, o uso do SingleTickerProviderStateMixin foi uma escolha excelente para garantir o gerenciamento correto do vsync no AnimationController.

Ícone de sugestão Para saber mais:

Documentação sobre Mixin para aprofundar o conhecimento.

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!