gradient_btn.dart 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_screenutil/flutter_screenutil.dart';
  4. import '../resource/assets.gen.dart';
  5. import '../resource/colors.gen.dart';
  6. import '../resource/string.gen.dart';
  7. /// 渐变色按钮
  8. class GradientBtn extends StatelessWidget {
  9. /// 纯色颜色
  10. final Color? color;
  11. /// 渐变颜色参数
  12. final List<Color> colors;
  13. /// 渐变方向
  14. final AlignmentGeometry begin;
  15. final AlignmentGeometry end;
  16. /// 按钮圆角半径
  17. final double radius;
  18. /// 内边距
  19. final EdgeInsetsGeometry? padding;
  20. /// 子组件
  21. final Widget child;
  22. /// 点击回调
  23. final VoidCallback onPressed;
  24. const GradientBtn({
  25. super.key,
  26. required this.colors,
  27. this.color,
  28. this.begin = Alignment.centerLeft,
  29. this.end = Alignment.centerRight,
  30. this.radius = 50,
  31. this.padding = const EdgeInsets.symmetric(vertical: 14),
  32. required this.child,
  33. required this.onPressed,
  34. });
  35. @override
  36. Widget build(BuildContext context) {
  37. Decoration decoration;
  38. // 优先使用纯色,如果没有纯色,则使用渐变色
  39. if (color != null) {
  40. decoration = BoxDecoration(
  41. color: color,
  42. borderRadius: BorderRadius.all(Radius.circular(radius)),
  43. );
  44. } else {
  45. // 渐变色
  46. decoration = ShapeDecoration(
  47. gradient: LinearGradient(colors: colors, begin: begin, end: end),
  48. shape: RoundedRectangleBorder(
  49. borderRadius: BorderRadius.circular(radius),
  50. ),
  51. );
  52. }
  53. return GestureDetector(
  54. onTap: () {
  55. onPressed();
  56. },
  57. child: Container(
  58. padding: padding,
  59. width: double.maxFinite,
  60. // 渐变背景
  61. decoration: decoration,
  62. child: Center(child: child),
  63. ),
  64. );
  65. }
  66. }
  67. /// 渐变按钮,中间为文字,文字左边是一个图标
  68. class GradientTextBtn extends StatelessWidget {
  69. /// 文字左边的图标
  70. final Image? leftIcon;
  71. /// 按钮文字
  72. final String text;
  73. /// 描述文字
  74. final String? desc;
  75. /// 纯色颜色
  76. final Color? color;
  77. /// 渐变颜色参数
  78. final List<Color> colors;
  79. /// 渐变方向
  80. final AlignmentGeometry begin;
  81. final AlignmentGeometry end;
  82. /// 按钮圆角半径
  83. final double radius;
  84. /// 内边距
  85. final EdgeInsetsGeometry? padding;
  86. /// 点击回调
  87. final VoidCallback onPressed;
  88. /// 操作按钮,带解锁按钮
  89. /// [isUnlock] 是否已解锁
  90. static GradientTextBtn withUnlock(
  91. bool isUnlock, {
  92. String? text,
  93. Color? color,
  94. String? desc,
  95. double radius = 50,
  96. EdgeInsetsGeometry? padding = const EdgeInsets.symmetric(vertical: 14),
  97. required VoidCallback onPressed,
  98. }) {
  99. String btnText = text ?? "";
  100. if (btnText.isEmpty) {
  101. btnText = StringName.intimacyUnlockAnalyse;
  102. }
  103. // 解锁图标,非VIP会员时,才显示锁图标
  104. Image? leftIcon;
  105. if (!isUnlock) {
  106. leftIcon = Assets.images.iconIntimacyAnalyseUnlock.image(
  107. width: 22,
  108. height: 22,
  109. );
  110. }
  111. return GradientTextBtn(
  112. btnText,
  113. desc: desc,
  114. color: color ?? ColorName.colorBrand,
  115. leftIcon: leftIcon,
  116. radius: radius,
  117. padding: padding,
  118. onPressed: onPressed,
  119. );
  120. }
  121. const GradientTextBtn(
  122. this.text, {
  123. super.key,
  124. this.leftIcon,
  125. this.desc,
  126. this.color,
  127. this.colors = const [ColorName.purpleGradient3, ColorName.purpleGradient4],
  128. this.begin = Alignment.centerLeft,
  129. this.end = Alignment.centerRight,
  130. this.radius = 50,
  131. this.padding = const EdgeInsets.symmetric(vertical: 14),
  132. required this.onPressed,
  133. });
  134. @override
  135. Widget build(BuildContext context) {
  136. String descStr = desc ?? "";
  137. return GradientBtn(
  138. color: color,
  139. colors: colors,
  140. radius: radius,
  141. onPressed: onPressed,
  142. padding: padding,
  143. child: Column(
  144. children: [
  145. Row(
  146. mainAxisAlignment: MainAxisAlignment.center,
  147. children: [
  148. // 左侧图标
  149. Visibility(
  150. visible: leftIcon != null,
  151. child: Container(
  152. margin: EdgeInsets.only(right: 4.w),
  153. child: leftIcon,
  154. ),
  155. ),
  156. // 文字
  157. Text(
  158. text,
  159. style: TextStyle(
  160. color: ColorName.white,
  161. fontSize: 16.sp,
  162. fontWeight: FontWeight.bold,
  163. ),
  164. ),
  165. ],
  166. ),
  167. // 描述
  168. Visibility(
  169. visible: descStr.isNotEmpty,
  170. child: Container(
  171. margin: EdgeInsets.only(top: 3.h),
  172. child: Text(
  173. descStr,
  174. style: TextStyle(
  175. color: ColorName.white,
  176. fontSize: 10.sp,
  177. fontWeight: FontWeight.w400,
  178. ),
  179. ),
  180. ),
  181. ),
  182. ],
  183. ),
  184. );
  185. }
  186. }