flutter_flow_icon_button.dart 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import 'package:flutter/material.dart';
  2. import 'package:font_awesome_flutter/font_awesome_flutter.dart';
  3. class FlutterFlowIconButton extends StatefulWidget {
  4. const FlutterFlowIconButton({
  5. Key? key,
  6. required this.icon,
  7. this.borderColor,
  8. this.borderRadius,
  9. this.borderWidth,
  10. this.buttonSize,
  11. this.fillColor,
  12. this.disabledColor,
  13. this.disabledIconColor,
  14. this.hoverColor,
  15. this.hoverIconColor,
  16. this.hoverBorderColor,
  17. this.onPressed,
  18. this.showLoadingIndicator = false,
  19. this.focusBorderSide,
  20. this.focusBorderRadius,
  21. }) : super(key: key);
  22. final Widget icon;
  23. final double? borderRadius;
  24. final double? buttonSize;
  25. final Color? fillColor;
  26. final Color? disabledColor;
  27. final Color? disabledIconColor;
  28. final Color? hoverColor;
  29. final Color? hoverIconColor;
  30. final Color? hoverBorderColor;
  31. final Color? borderColor;
  32. final double? borderWidth;
  33. final bool showLoadingIndicator;
  34. final Function()? onPressed;
  35. final BorderSide? focusBorderSide;
  36. final BorderRadius? focusBorderRadius;
  37. @override
  38. State<FlutterFlowIconButton> createState() => _FlutterFlowIconButtonState();
  39. }
  40. class _FlutterFlowIconButtonState extends State<FlutterFlowIconButton> {
  41. bool loading = false;
  42. late double? iconSize;
  43. late Color? iconColor;
  44. late Widget effectiveIcon;
  45. @override
  46. void initState() {
  47. super.initState();
  48. _updateIcon();
  49. }
  50. @override
  51. void didUpdateWidget(FlutterFlowIconButton oldWidget) {
  52. super.didUpdateWidget(oldWidget);
  53. _updateIcon();
  54. }
  55. void _updateIcon() {
  56. final isFontAwesome = widget.icon is FaIcon;
  57. if (isFontAwesome) {
  58. FaIcon icon = widget.icon as FaIcon;
  59. effectiveIcon = FaIcon(
  60. icon.icon,
  61. size: icon.size,
  62. );
  63. iconSize = icon.size;
  64. iconColor = icon.color;
  65. } else {
  66. Icon icon = widget.icon as Icon;
  67. effectiveIcon = Icon(
  68. icon.icon,
  69. size: icon.size,
  70. );
  71. iconSize = icon.size;
  72. iconColor = icon.color;
  73. }
  74. }
  75. @override
  76. Widget build(BuildContext context) {
  77. ButtonStyle style = ButtonStyle(
  78. shape: MaterialStateProperty.resolveWith<OutlinedBorder>(
  79. (states) {
  80. if (states.contains(MaterialState.hovered)) {
  81. return RoundedRectangleBorder(
  82. borderRadius: BorderRadius.circular(widget.borderRadius ?? 0),
  83. side: BorderSide(
  84. color: widget.hoverBorderColor ??
  85. widget.borderColor ??
  86. Colors.transparent,
  87. width: widget.borderWidth ?? 0,
  88. ),
  89. );
  90. }
  91. if (states.contains(WidgetState.focused) &&
  92. widget.focusBorderSide != null) {
  93. return RoundedRectangleBorder(
  94. borderRadius:
  95. widget.focusBorderRadius ?? BorderRadius.circular(8),
  96. side: widget.focusBorderSide!,
  97. );
  98. }
  99. return RoundedRectangleBorder(
  100. borderRadius: BorderRadius.circular(widget.borderRadius ?? 0),
  101. side: BorderSide(
  102. color: widget.borderColor ?? Colors.transparent,
  103. width: widget.borderWidth ?? 0,
  104. ),
  105. );
  106. },
  107. ),
  108. iconColor: MaterialStateProperty.resolveWith<Color?>(
  109. (states) {
  110. if (states.contains(MaterialState.disabled) &&
  111. widget.disabledIconColor != null) {
  112. return widget.disabledIconColor;
  113. }
  114. if (states.contains(MaterialState.hovered) &&
  115. widget.hoverIconColor != null) {
  116. return widget.hoverIconColor;
  117. }
  118. return iconColor;
  119. },
  120. ),
  121. backgroundColor: MaterialStateProperty.resolveWith<Color?>(
  122. (states) {
  123. if (states.contains(MaterialState.disabled) &&
  124. widget.disabledColor != null) {
  125. return widget.disabledColor;
  126. }
  127. if (states.contains(MaterialState.hovered) &&
  128. widget.hoverColor != null) {
  129. return widget.hoverColor;
  130. }
  131. return widget.fillColor;
  132. },
  133. ),
  134. overlayColor: MaterialStateProperty.resolveWith<Color?>((states) {
  135. if (states.contains(MaterialState.pressed)) {
  136. return null;
  137. }
  138. return widget.hoverColor == null ? null : Colors.transparent;
  139. }),
  140. );
  141. return SizedBox(
  142. width: widget.buttonSize,
  143. height: widget.buttonSize,
  144. child: Theme(
  145. data: ThemeData.from(
  146. colorScheme: Theme.of(context).colorScheme,
  147. useMaterial3: true,
  148. ),
  149. child: IgnorePointer(
  150. ignoring: (widget.showLoadingIndicator && loading),
  151. child: IconButton(
  152. icon: (widget.showLoadingIndicator && loading)
  153. ? Container(
  154. width: iconSize,
  155. height: iconSize,
  156. child: CircularProgressIndicator(
  157. valueColor: AlwaysStoppedAnimation<Color>(
  158. iconColor ?? Colors.white,
  159. ),
  160. ),
  161. )
  162. : effectiveIcon,
  163. onPressed: widget.onPressed == null
  164. ? null
  165. : () async {
  166. if (loading) {
  167. return;
  168. }
  169. setState(() => loading = true);
  170. try {
  171. await widget.onPressed!();
  172. } finally {
  173. if (mounted) {
  174. setState(() => loading = false);
  175. }
  176. }
  177. },
  178. splashRadius: widget.buttonSize,
  179. style: style,
  180. ),
  181. ),
  182. ),
  183. );
  184. }
  185. }