load_switch.dart 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import 'package:animated_toggle_switch/animated_toggle_switch.dart';
  2. import 'package:flutter/material.dart';
  3. typedef LoadFutureCallback = Future<bool> Function(bool value);
  4. class LoadSwitch extends StatefulWidget {
  5. final bool value;
  6. final double height;
  7. final double borderWidth;
  8. final Color loadingColor;
  9. final Color selectedColor;
  10. final Color unselectedColor;
  11. final LoadFutureCallback future;
  12. const LoadSwitch(
  13. {super.key,
  14. required this.value,
  15. required this.height,
  16. required this.future,
  17. this.borderWidth = 5,
  18. this.loadingColor = Colors.blue,
  19. this.selectedColor = Colors.green,
  20. this.unselectedColor = Colors.red});
  21. @override
  22. State<LoadSwitch> createState() => _LoadSwitchState();
  23. }
  24. class _LoadSwitchState extends State<LoadSwitch> {
  25. bool isSelected = false;
  26. @override
  27. void initState() {
  28. // TODO: implement initState
  29. super.initState();
  30. isSelected = widget.value;
  31. }
  32. @override
  33. Widget build(BuildContext context) {
  34. return CustomAnimatedToggleSwitch(
  35. height: widget.height,
  36. indicatorSize: Size.square(widget.height),
  37. current: isSelected,
  38. values: const [false, true],
  39. onChanged: (value) async {
  40. bool newValue = await widget.future(value);
  41. setState(() {
  42. isSelected = newValue;
  43. });
  44. },
  45. animationDuration: const Duration(milliseconds: 350),
  46. // iconArrangement: IconArrangement.overlap,
  47. // spacing: -16.0,
  48. wrapperBuilder: (context, global, child) => DecoratedBox(
  49. decoration: BoxDecoration(
  50. color: Color.lerp(
  51. Color.lerp(widget.unselectedColor, widget.selectedColor,
  52. global.position),
  53. Colors.grey,
  54. global.loadingAnimationValue),
  55. borderRadius:
  56. BorderRadius.all(Radius.circular(widget.height / 2))),
  57. child: child),
  58. foregroundIndicatorBuilder: (context, global) {
  59. return Stack(
  60. fit: StackFit.expand,
  61. children: [
  62. Padding(
  63. padding: EdgeInsets.all(widget.borderWidth),
  64. child: const DecoratedBox(
  65. decoration: BoxDecoration(
  66. shape: BoxShape.circle, color: Colors.white)),
  67. ),
  68. Padding(
  69. padding: EdgeInsets.all(widget.borderWidth / 2),
  70. child: CircularProgressIndicator(
  71. strokeWidth: widget.borderWidth,
  72. color: widget.loadingColor
  73. .withOpacity(global.loadingAnimationValue),
  74. ),
  75. ),
  76. ],
  77. );
  78. },
  79. iconBuilder: (context, local, global) => const SizedBox(),
  80. );
  81. }
  82. }