Estava me confundindo na hora de fazer a animação da cor, principalmente na hora de alterar os valores do ARGB
(principalmente porque a meu tema do app é diferente, então ficaria bem mais complexo). Como um solução, meu Animation
recebe um ColorTween
, no qual eu posso passar diretamente Colors
e o Flutter
faz a mágica depois.
Para isso, separarei a lógica da animação em um mixin
:
import 'package:clean_arch_project/utils/consts/my_themes.dart';
import 'package:flutter/material.dart';
mixin ColorAnimationMixin<T extends StatefulWidget> on State<T> {
late final AnimationController colorAnimationController;
late final Animation<Color?> colorAnimation;
TickerProvider get tickerProvider => this as TickerProvider;
@override
void initState() {
super.initState();
colorAnimationController = AnimationController(
vsync: tickerProvider,
duration: const Duration(
milliseconds: 1500,
),
)..repeat(
reverse: true,
);
colorAnimation = ColorTween(
begin: const Color.fromARGB(255, 15, 133, 103),
end: ThemeColors.iconColor,
).animate(
CurvedAnimation(
parent: colorAnimationController,
curve: Curves.easeIn,
),
);
}
@override
void dispose() {
colorAnimationController.dispose();
super.dispose();
}
}
Depois chamei essa animação na minha tela, "importando" esse mixin
com o with
no meu State
. Já para executá-la, eu uso o colorAnimation
(do mixin
) no AnimatedBuilder
:
class _CategoryComponentState extends State<CategoryComponent>
with ScaleAnimationMixin, ColorAnimationMixin, TickerProviderStateMixin {
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: colorAnimation,
builder: (context, child) {
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,
color: colorAnimation.value ??
Colors.transparent,
),
),
)
: 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,
),
),
],
);
});
}
}