step_card.dart 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter_screenutil/flutter_screenutil.dart';
  3. import '../../../resource/colors.gen.dart';
  4. import '../../../widget/gradient_text.dart';
  5. import '../intimacy_analyse_upload/widget/step_label_widget.dart';
  6. /// 步骤卡片,支持设置卡片背景、步骤标题、步骤描述、顶部图标和内容区域
  7. class StepCard extends StatelessWidget {
  8. /// 卡片背景
  9. final ImageProvider bgImageProvider;
  10. /// 顶部标题区域的组件
  11. final Widget? topTitleWidget;
  12. /// 顶部图标组件
  13. final Image? topIconWidget;
  14. /// 内容组件
  15. final Widget contentWidget;
  16. const StepCard({
  17. super.key,
  18. required this.bgImageProvider,
  19. this.topTitleWidget,
  20. required this.contentWidget,
  21. this.topIconWidget,
  22. });
  23. @override
  24. Widget build(BuildContext context) {
  25. return Container(
  26. margin: EdgeInsets.only(left: 12.w, top: 10.h, right: 12.w),
  27. child: Stack(
  28. // 不裁切超出区域的子组件,例如下面的顶部的图标
  29. clipBehavior: Clip.none,
  30. children: [
  31. // 顶部的图标
  32. topIconWidget == null
  33. ? SizedBox()
  34. : Positioned(top: -11.h, right: 0, child: topIconWidget!),
  35. // 卡片背景
  36. Container(
  37. // 渐变背景
  38. // decoration: BoxDecoration(
  39. // gradient: LinearGradient(
  40. // colors: [Color(0xFFEFE9FF), Color(0xFFFBFAFF)],
  41. // begin: Alignment.topCenter,
  42. // end: Alignment.bottomRight,
  43. // ),
  44. // shape: BoxShape.rectangle,
  45. // border: Border.all(color: ColorName.white80, width: 1.w),
  46. // borderRadius: BorderRadius.all(Radius.circular(20.r)),
  47. // ),
  48. // 卡片背景
  49. decoration: BoxDecoration(
  50. image: DecorationImage(image: bgImageProvider, fit: BoxFit.fill),
  51. ),
  52. child: Column(
  53. // 左对齐
  54. crossAxisAlignment: CrossAxisAlignment.start,
  55. children: [
  56. // 顶部标题区域
  57. topTitleWidget != null ? topTitleWidget! : SizedBox(),
  58. // 内容区域
  59. contentWidget,
  60. SizedBox(height: 12.h),
  61. ],
  62. ),
  63. ),
  64. ],
  65. ),
  66. );
  67. }
  68. }
  69. /// 步骤标题组件
  70. class StepTitleWidget extends StatelessWidget {
  71. /// 步骤标签
  72. final String stepLabel;
  73. /// 步骤标题
  74. final String stepTitle;
  75. /// 步骤描述
  76. final String stepDesc;
  77. const StepTitleWidget({
  78. super.key,
  79. this.stepLabel = "",
  80. this.stepTitle = "",
  81. this.stepDesc = "",
  82. });
  83. @override
  84. Widget build(BuildContext context) {
  85. return Column(
  86. children: [
  87. // 步骤标题
  88. Container(
  89. margin: EdgeInsets.only(top: 16.h, bottom: 4.h),
  90. child: _buildStepTitle(),
  91. ),
  92. // 步骤描述
  93. stepDesc.isNotEmpty ? _buildStepDesc(stepDesc) : SizedBox(height: 6.h),
  94. ],
  95. );
  96. }
  97. /// 步骤标题
  98. Widget _buildStepTitle() {
  99. return Container(
  100. padding: EdgeInsets.only(left: 12.w),
  101. child: Row(
  102. children: [
  103. // 步骤标签
  104. Visibility(
  105. visible: stepLabel.isNotEmpty,
  106. child: Container(
  107. margin: EdgeInsets.only(right: 10.w),
  108. child: StepLabelWidget(label: stepLabel),
  109. ),
  110. ),
  111. // 标题
  112. GradientText(
  113. // 渐变颜色
  114. colors: [ColorName.stepTitleColor1, ColorName.stepTitleColor2],
  115. child: Text(
  116. stepTitle,
  117. style: TextStyle(fontSize: 20.sp, fontWeight: FontWeight.w700),
  118. ),
  119. ),
  120. ],
  121. ),
  122. );
  123. }
  124. /// 构建步骤描述
  125. Widget _buildStepDesc(String desc) {
  126. if (desc.isEmpty) {
  127. return SizedBox();
  128. }
  129. return Row(
  130. children: [
  131. Expanded(
  132. child: Container(
  133. margin: EdgeInsets.only(left: 12.w, right: 12.w),
  134. child: Text(
  135. desc,
  136. // 超过时显示省略号
  137. overflow: TextOverflow.ellipsis,
  138. // 最多多少行
  139. maxLines: 1,
  140. style: TextStyle(
  141. fontSize: 12.sp,
  142. fontWeight: FontWeight.w400,
  143. color: ColorName.black60,
  144. ),
  145. ),
  146. ),
  147. ),
  148. SizedBox(height: 16.h),
  149. ],
  150. );
  151. }
  152. }