Przeglądaj źródła

[feat]亲密度分析,报告卡片,进度条上方,增加气泡进度显示

hezihao 7 miesięcy temu
rodzic
commit
1d728684e1

+ 10 - 5
lib/module/intimacy_analyse/widget/intimacy_analyse_report_widget.dart

@@ -34,7 +34,7 @@ class ExistReportCardWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return ReportCardFrameWidget(
-      height: 825.h,
+      height: 850.h,
       child: Column(
         mainAxisSize: MainAxisSize.min,
         children: [
@@ -60,6 +60,7 @@ class ExistReportCardWidget extends StatelessWidget {
         children: [
           // 概览数值
           Container(
+            padding: EdgeInsets.symmetric(horizontal: 18.w),
             decoration: BoxDecoration(
               color: ColorName.bgReportOverview,
               borderRadius: BorderRadius.all(Radius.circular(10.r)),
@@ -67,14 +68,12 @@ class ExistReportCardWidget extends StatelessWidget {
             child: Row(
               children: [
                 _buildIntimacyOverviewItem("30"),
-                SizedBox(width: 29.w),
                 _buildOverviewDivider(),
-                SizedBox(width: 29.w),
                 _buildCurrentStageOverviewItem("相互了解"),
               ],
             ),
           ),
-          SizedBox(height: 12.h),
+          SizedBox(height: 36.h),
           // 图表
           _buildChart(),
         ],
@@ -96,6 +95,8 @@ class ExistReportCardWidget extends StatelessWidget {
   Widget _buildIntimacyOverviewItem(String value) {
     return Expanded(
       child: Row(
+        // 左对齐
+        mainAxisAlignment: MainAxisAlignment.start,
         children: [
           // 图表
           Assets.images.iconIntimacyAnalyseReportOverviewLove.image(
@@ -150,6 +151,8 @@ class ExistReportCardWidget extends StatelessWidget {
   Widget _buildCurrentStageOverviewItem(String value) {
     return Expanded(
       child: Row(
+        // 右对齐
+        mainAxisAlignment: MainAxisAlignment.end,
         children: [
           // 图标
           Assets.images.iconIntimacyAnalyseReportOverviewStage.image(
@@ -274,10 +277,12 @@ class ExistReportCardWidget extends StatelessWidget {
         // 进度条
         Expanded(
           child: AnimatedGradientProgressBar(
+            // 进度值
             targetValue: value,
             // 渐变色
             gradient: LinearGradient(colors: progressColors),
-            duration: const Duration(seconds: 1),
+            // 动画时长
+            duration: const Duration(milliseconds: 1500),
           ),
         ),
       ],

+ 72 - 49
lib/widget/animated_progress_bar.dart

@@ -1,5 +1,7 @@
 import 'package:flutter/material.dart';
 
+import 'bubble/bubble_widget.dart';
+
 /// 支持动画过渡和渐变色的进度条
 // 使用示例
 // AnimatedGradientProgressBar(
@@ -94,59 +96,80 @@ class AnimatedGradientProgressBarState
 
   @override
   Widget build(BuildContext context) {
-    return Stack(
-      // 允许子组件溢出自己本身的大小,默认是裁切的
-      clipBehavior: Clip.none,
-      children: [
-        // 百分比文本
-        Positioned(
-          right: 0,
-          // 文字位于进度条上方
-          bottom: widget.height + 4,
-          child: AnimatedBuilder(
-            animation: _animation,
-            builder: (context, _) {
-              return Text(
-                '${(_animation.value * 100).toStringAsFixed(0)}%',
-                style: const TextStyle(fontSize: 12, color: Colors.black54),
-              );
-            },
-          ),
-        ),
-        // 进度条
-        ClipRRect(
-          borderRadius: BorderRadius.circular(widget.borderRadius),
-          child: Container(
-            width: double.infinity,
-            height: widget.height,
-            decoration: BoxDecoration(
-              color: Colors.grey[200],
-              borderRadius: BorderRadius.circular(widget.borderRadius),
+    return LayoutBuilder(
+      builder: (context, constraints) {
+        // 进度条的实际宽度
+        final progressBarWidth = constraints.maxWidth;
+        return Stack(
+          // 允许子组件溢出自己本身的大小,默认是裁切的
+          clipBehavior: Clip.none,
+          children: [
+            // 百分比文本
+            Positioned(
+              // 左侧偏移量,跟随当前进度的末尾,公式:当前比例值 * 进度条的宽度 - 气泡宽度
+              left:  widget.targetValue * progressBarWidth - (widget.targetValue > 0.5 ? 32 : 24),
+              // 进度气泡,位于进度条上方
+              bottom: widget.height + 0.85,
+              child: AnimatedBuilder(
+                animation: _animation,
+                builder: (context, _) {
+                  return BubbleWidget(
+                    // 箭头方向
+                    arrowDirection: AxisDirection.down,
+                    arrowOffset: 22,
+                    arrowLength: 8,
+                    arrowRadius: 2,
+                    arrowWidth: 5,
+                    padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 7),
+                    borderRadius: BorderRadius.circular(9),
+                    // 气泡的背景颜色,取渐变色的第2个颜色
+                    backgroundColor: widget.gradient.colors.last,
+                    contentBuilder: (context) {
+                      return Text(
+                        '${(_animation.value * 100).toStringAsFixed(0)}%',
+                        style: const TextStyle(fontSize: 10, color: Colors.white),
+                      );
+                    },
+                  );
+                },
+              ),
             ),
-            child: Stack(
-              children: [
-                AnimatedBuilder(
-                  animation: _animation,
-                  builder: (context, _) {
-                    return FractionallySizedBox(
-                      widthFactor: _animation.value,
-                      alignment: Alignment.centerLeft,
-                      child: Container(
-                        decoration: BoxDecoration(
-                          gradient: widget.gradient,
-                          borderRadius: BorderRadius.circular(
-                            widget.borderRadius,
+            // 进度条
+            ClipRRect(
+              borderRadius: BorderRadius.circular(widget.borderRadius),
+              child: Container(
+                width: double.infinity,
+                height: widget.height,
+                decoration: BoxDecoration(
+                  color: Colors.grey[200],
+                  borderRadius: BorderRadius.circular(widget.borderRadius),
+                ),
+                child: Stack(
+                  children: [
+                    AnimatedBuilder(
+                      animation: _animation,
+                      builder: (context, _) {
+                        return FractionallySizedBox(
+                          widthFactor: _animation.value,
+                          alignment: Alignment.centerLeft,
+                          child: Container(
+                            decoration: BoxDecoration(
+                              gradient: widget.gradient,
+                              borderRadius: BorderRadius.circular(
+                                widget.borderRadius,
+                              ),
+                            ),
                           ),
-                        ),
-                      ),
-                    );
-                  },
+                        );
+                      },
+                    ),
+                  ],
                 ),
-              ],
+              ),
             ),
-          ),
-        ),
-      ],
+          ],
+        );
+      }
     );
   }
 }