我刚刚制作了一个动画复选框,其中颜色是动画的。这是代码:
import 'package:flutter/material.dart';
import 'package:sizer/sizer.dart';
class CustomCheckbox extends StatefulWidget {
final Color activeColor;
final Color iconColor;
late bool isVisible = false;
late Color backgroundColor = Colors.transparent;
CustomCheckbox({Key? key, required this.activeColor, required this.iconColor}) : super(key: key);
@override
_CustomCheckboxState createState() => _CustomCheckboxState();
}
class _CustomCheckboxState extends State<CustomCheckbox> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<Color?> _backgroundColorAnimation;
late Animation<Color?> _iconColorAnimation;
@override
void initState() {
super.initState();
//Create the Animation Controller
_controller = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this, //Refer to this widget
);
//Create 2 Animation for the Colors
_backgroundColorAnimation = ColorTween(begin: Colors.transparent, end: widget.activeColor)
.animate(_controller);
_iconColorAnimation = ColorTween(begin: Colors.transparent, end: widget.iconColor)
.animate(_controller);
_controller.addListener(() {
print (_backgroundColorAnimation.value);
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, _) {
return Container(
decoration: BoxDecoration(
color: _backgroundColorAnimation.value,
border: Border.all(
width: 0.3.w,
color: Theme.of(context).splashColor,
),
borderRadius: BorderRadius.circular(0.8.w),
),
child: InkWell(
highlightColor : Colors.transparent,
splashColor: Colors.transparent,
child: Visibility(
//Maintain the space where the widget is even if it is hid
maintainAnimation: true,
maintainState: true,
maintainSize: true,
visible: widget.isVisible,
child: Icon(
Icons.check_outlined,
size: 4.w,
color: _iconColorAnimation.value,
),
),
onTap: () {
setState(() {
widget.isVisible = !widget.isVisible;
if (widget.backgroundColor == Colors.transparent){
widget.backgroundColor = widget.activeColor;
//Put the animation forward if the checkbox is unchecked
_controller.forward();
} else{
widget.backgroundColor = Colors.transparent;
//Put the animation reverse if the checkbox is checked
_controller.reverse();
}
});
},
),
);
},
);
}
}
我想测试颜色是否正确,所以我做了一个小部件测试来测试它:
testWidgets('CustomCheckbox Test', (WidgetTester tester) async{
await tester.pumpWidget(Sizer(
builder: (context, orientation, deviceType) {
return MaterialApp(
home: Material(
child: CustomCheckbox(
iconColor: Colors.purple,
activeColor: Colors.yellow,
)
),
);
}
));
final container = tester.widget<Container>(find.byType(Container)).decoration as BoxDecoration;
final icon = tester.widget<Icon>(find.byType(Icon));
expect(container.color, Colors.transparent);
expect(icon.color, Colors.transparent);
expect(find.byIcon(Icons.check_outlined),findsOneWidget);
await tester.tap(find.byType(InkWell));
await tester.pump(const Duration(milliseconds: 1000));
print(container);
print (icon);
});
问题是当我泵送小部件时,颜色根本没有改变,我得到了这些结果:
Testing started at 14:46 ...
Color(0x00000000)
BoxDecoration(color: Color(0x00000000), border: Border.all(BorderSide(Color(0x66c8c8c8), 1.8, BorderStyle.solid)), borderRadius: BorderRadius.circular(4.8))
Icon(IconData(U+0EF49), size: 24.0, color: Color(0x00000000))
Color(0x00000000)
似乎动画只迭代了2次,我不知道为什么......
感谢您的建议!
克里斯