kidd3166 3 years ago
parent
commit
820ec77654

+ 3 - 2
lib/pages/home/duration_page.dart

@@ -90,7 +90,7 @@ class _PageState extends State<DurationPage> {
                             child: CircularPercentIndicator(
                               radius: 140.0,
                               lineWidth: 12.0,
-                              percent: min(1.0, 1.0 * (snapshot.data?.today?.value ?? 0) / snapshot.data?.today?.valueTarget ?? 0.01),
+                              percent: 1.0 * (snapshot.data?.today?.value ?? 0) / snapshot.data?.today?.valueTarget ?? 0.01,
                               center: Column(
                                 children: <Widget>[
                                   Text(
@@ -108,7 +108,8 @@ class _PageState extends State<DurationPage> {
                               animation: true,
                               animationDuration: 1000,
                               animateFromLastPercent: true,
-                              startAngle: 5,
+                              startAngle: 200.0,
+                              arcType: ArcType.CUSTOM,
                               backgroundColor: Color(0xfff1f1f1),
                               circularStrokeCap: CircularStrokeCap.round,
                               rotateLinearGradient: true,

+ 3 - 2
lib/pages/home/home_info_page.dart

@@ -352,7 +352,7 @@ class _PageState extends ViewStateLifecycle<HomeInfoPage, SportIndexModel> with
                               child: CircularPercentIndicator(
                                 radius: 100.0,
                                 lineWidth: 10.0,
-                                percent: min(1.0, 1.0 * (model?.data?.today?.value(model.data?.target?.type) ?? 0) / (model.data?.target?.valueTarget ?? 0.01)),
+                                percent: 1.0 * (model?.data?.today?.value(model.data?.target?.type) ?? 0) / (model.data?.target?.valueTarget ?? 0.01),
                                 center: Column(
                                   children: <Widget>[
                                     SizedBox(
@@ -374,7 +374,8 @@ class _PageState extends ViewStateLifecycle<HomeInfoPage, SportIndexModel> with
                                 animation: true,
                                 animationDuration: 1000,
                                 animateFromLastPercent: true,
-                                startAngle: 5,
+                                startAngle: 200.0,
+                                arcType: ArcType.CUSTOM,
                                 backgroundColor: Color(0xfff1f1f1),
                                 circularStrokeCap: CircularStrokeCap.round,
                                 rotateLinearGradient: true,

+ 40 - 8
lib/pages/social/new_social_index_page.dart

@@ -1,6 +1,6 @@
+import 'dart:math';
 import 'dart:ui';
 
-import 'package:cached_network_image/cached_network_image.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/rendering.dart';
@@ -10,7 +10,6 @@ import 'package:provider/provider.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 import 'package:sport/bean/forum.dart';
 import 'package:sport/bean/post.dart';
-import 'package:sport/pages/social/post_detail_page.dart';
 import 'package:sport/pages/social/post_page.dart';
 import 'package:sport/pages/social/post_widget.dart';
 import 'package:sport/pages/social/search_page.dart';
@@ -74,7 +73,7 @@ class _PageState extends ViewStateLifecycle<NewSocialIndexPage, SocialDetailMode
   ];
   ValueNotifier<bool> isShowSelect = ValueNotifier(false);
 
-  void _refresh(){
+  void _refresh() {
     model?.setForumIdAndOrigin(_tabController.index, forumId, isOfficial);
     _controller.animateTo(0, duration: Duration(milliseconds: 100), curve: Curves.ease);
   }
@@ -105,7 +104,6 @@ class _PageState extends ViewStateLifecycle<NewSocialIndexPage, SocialDetailMode
         }
       });
     initButtonList();
-
   }
 
   @override
@@ -177,7 +175,7 @@ class _PageState extends ViewStateLifecycle<NewSocialIndexPage, SocialDetailMode
             color: index == targetIndex.value ? Theme.of(context).accentColor : Colors.white,
             borderRadius: BorderRadius.all(Radius.circular(20.0)),
             border: Border.all(color: index == targetIndex.value ? Colors.white : Theme.of(context).dividerTheme.color)),
-        padding: EdgeInsets.symmetric(vertical: 8.0,horizontal: 25.0),
+        padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 25.0),
         child: Text(
           data.gameName,
           strutStyle: StrutStyle(forceStrutHeight: true),
@@ -490,6 +488,7 @@ class _PageState extends ViewStateLifecycle<NewSocialIndexPage, SocialDetailMode
               });
         },
       ),
+      floatingActionButtonLocation: _EndFloatFloatingActionButtonLocation(),
       floatingActionButton: InkWell(
         child: Image.asset("lib/assets/img/bbs_icon_edit.png"),
         onTap: () async {
@@ -500,16 +499,49 @@ class _PageState extends ViewStateLifecycle<NewSocialIndexPage, SocialDetailMode
                     "",
                     forums: buttonList,
                   ));
-          if(result == true){
+          if (result == true) {
             if (_tabController.index.toDouble() == _tabController.animation.value) {
               _refresh();
-            }else{
+            } else {
               _tabController?.index = 2;
             }
-
           }
         },
       ),
     );
   }
 }
+
+class _EndFloatFloatingActionButtonLocation extends FloatingActionButtonLocation {
+  const _EndFloatFloatingActionButtonLocation();
+
+  double _rightOffset(ScaffoldPrelayoutGeometry scaffoldGeometry, {double offset = 0.0}) {
+    return scaffoldGeometry.scaffoldSize.width - scaffoldGeometry.minInsets.right - scaffoldGeometry.floatingActionButtonSize.width + offset;
+  }
+
+  double getDockedY(ScaffoldPrelayoutGeometry scaffoldGeometry) {
+    final double contentBottom = scaffoldGeometry.contentBottom;
+    final double bottomSheetHeight = scaffoldGeometry.bottomSheetSize.height;
+    final double fabHeight = scaffoldGeometry.floatingActionButtonSize.height;
+    final double snackBarHeight = scaffoldGeometry.snackBarSize.height;
+
+    double fabY = contentBottom - fabHeight / 2.0;
+    // The FAB should sit with a margin between it and the snack bar.
+    if (snackBarHeight > 0.0) fabY = min(fabY, contentBottom - snackBarHeight - fabHeight - kFloatingActionButtonMargin);
+    // The FAB should sit with its center in front of the top of the bottom sheet.
+    if (bottomSheetHeight > 0.0) fabY = min(fabY, contentBottom - bottomSheetHeight - fabHeight / 2.0);
+
+    final double maxFabY = scaffoldGeometry.scaffoldSize.height - fabHeight;
+    return min(maxFabY, fabY);
+  }
+
+  @override
+  Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) {
+    final double fabX = _rightOffset(scaffoldGeometry, offset: -8.0);
+    final double fabY = getDockedY(scaffoldGeometry);
+    return Offset(fabX, fabY - 8);
+  }
+
+  @override
+  String toString() => 'FloatingActionButtonLocation.endFloat';
+}

+ 69 - 73
lib/widgets/circular_percent_indicator.dart

@@ -5,10 +5,7 @@ import 'dart:math' as math;
 
 enum CircularStrokeCap { butt, round, square }
 
-enum ArcType {
-  HALF,
-  FULL,
-}
+enum ArcType { HALF, FULL, CUSTOM }
 
 // ignore: must_be_immutable
 class CircularPercentIndicator extends StatefulWidget {
@@ -98,8 +95,7 @@ class CircularPercentIndicator extends StatefulWidget {
       this.fillColor = Colors.transparent,
       this.backgroundColor = const Color(0xFFB8C7CB),
       Color progressColor,
-      this.backgroundWidth =
-          -1, //negative values ignored, replaced with lineWidth
+      this.backgroundWidth = -1, //negative values ignored, replaced with lineWidth
       this.linearGradient,
       this.animation = false,
       this.animationDuration = 500,
@@ -120,14 +116,13 @@ class CircularPercentIndicator extends StatefulWidget {
       this.rotateLinearGradient = false})
       : super(key: key) {
     if (linearGradient != null && progressColor != null) {
-      throw ArgumentError(
-          'Cannot provide both linearGradient and progressColor');
+      throw ArgumentError('Cannot provide both linearGradient and progressColor');
     }
     _progressColor = progressColor ?? Colors.red;
 
     assert(startAngle >= 0.0);
     assert(curve != null);
-    if (percent < 0.0 || percent > 1.0) {
+    if (percent < 0.0) {
       throw Exception("Percent value must be a double between 0.0 and 1.0");
     }
 
@@ -137,12 +132,10 @@ class CircularPercentIndicator extends StatefulWidget {
   }
 
   @override
-  _CircularPercentIndicatorState createState() =>
-      _CircularPercentIndicatorState();
+  _CircularPercentIndicatorState createState() => _CircularPercentIndicatorState();
 }
 
-class _CircularPercentIndicatorState extends State<CircularPercentIndicator>
-    with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
+class _CircularPercentIndicatorState extends State<CircularPercentIndicator> with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
   AnimationController _animationController;
   Animation _animation;
   double _percent = 0.0;
@@ -158,9 +151,7 @@ class _CircularPercentIndicatorState extends State<CircularPercentIndicator>
   @override
   void initState() {
     if (widget.animation) {
-      _animationController = AnimationController(
-          vsync: this,
-          duration: Duration(milliseconds: widget.animationDuration));
+      _animationController = AnimationController(vsync: this, duration: Duration(milliseconds: widget.animationDuration));
       _animation = Tween(begin: 0.0, end: widget.percent).animate(
         CurvedAnimation(parent: _animationController, curve: widget.curve),
       )..addListener(() {
@@ -172,8 +163,7 @@ class _CircularPercentIndicatorState extends State<CircularPercentIndicator>
           }
         });
       _animationController.addStatusListener((status) {
-        if (widget.onAnimationEnd != null &&
-            status == AnimationStatus.completed) {
+        if (widget.onAnimationEnd != null && status == AnimationStatus.completed) {
           widget.onAnimationEnd();
         }
       });
@@ -185,9 +175,7 @@ class _CircularPercentIndicatorState extends State<CircularPercentIndicator>
   }
 
   void _checkIfNeedCancelAnimation(CircularPercentIndicator oldWidget) {
-    if (oldWidget.animation &&
-        !widget.animation &&
-        _animationController != null) {
+    if (oldWidget.animation && !widget.animation && _animationController != null) {
       _animationController.stop();
     }
   }
@@ -195,15 +183,10 @@ class _CircularPercentIndicatorState extends State<CircularPercentIndicator>
   @override
   void didUpdateWidget(CircularPercentIndicator oldWidget) {
     super.didUpdateWidget(oldWidget);
-    if (oldWidget.percent != widget.percent ||
-        oldWidget.startAngle != widget.startAngle) {
+    if (oldWidget.percent != widget.percent || oldWidget.startAngle != widget.startAngle) {
       if (_animationController != null) {
-        _animationController.duration =
-            Duration(milliseconds: widget.animationDuration);
-        _animation = Tween(
-                begin: widget.animateFromLastPercent ? oldWidget.percent : 0.0,
-                end: widget.percent)
-            .animate(
+        _animationController.duration = Duration(milliseconds: widget.animationDuration);
+        _animation = Tween(begin: widget.animateFromLastPercent ? oldWidget.percent : 0.0, end: widget.percent).animate(
           CurvedAnimation(parent: _animationController, curve: widget.curve),
         );
         _animationController.forward(from: 0.0);
@@ -235,42 +218,33 @@ class _CircularPercentIndicatorState extends State<CircularPercentIndicator>
           children: [
             CustomPaint(
               painter: CirclePainter(
-                  progress: _percent * 360,
+                  progress: math.min(360, _percent * 360),
                   progressColor: widget.progressColor,
+                  progressOver: math.max(0, _percent -1),
                   backgroundColor: widget.backgroundColor,
                   startAngle: widget.startAngle,
                   circularStrokeCap: widget.circularStrokeCap,
                   radius: (widget.radius / 2) - widget.lineWidth / 2,
                   lineWidth: widget.lineWidth,
                   backgroundWidth: //negative values ignored, replaced with lineWidth
-                      widget.backgroundWidth >= 0.0
-                          ? (widget.backgroundWidth)
-                          : widget.lineWidth,
+                      widget.backgroundWidth >= 0.0 ? (widget.backgroundWidth) : widget.lineWidth,
                   arcBackgroundColor: widget.arcBackgroundColor,
                   arcType: widget.arcType,
                   reverse: widget.reverse,
                   linearGradient: widget.linearGradient,
                   maskFilter: widget.maskFilter,
                   rotateLinearGradient: widget.rotateLinearGradient),
-              child: (widget.center != null)
-                  ? Center(child: widget.center)
-                  : Container(),
+              child: (widget.center != null) ? Center(child: widget.center) : Container(),
             ),
             if (widget.widgetIndicator != null && widget.animation)
               Positioned.fill(
                 child: Transform.rotate(
-                  angle: radians(
-                      (widget.circularStrokeCap != CircularStrokeCap.butt &&
-                              widget.reverse)
-                          ? -15
-                          : 0),
+                  angle: radians((widget.circularStrokeCap != CircularStrokeCap.butt && widget.reverse) ? -15 : 0),
                   child: Transform.rotate(
                     angle: radians((widget.reverse ? -360 : 360) * _percent),
                     child: Transform.translate(
                       offset: Offset(
-                        (widget.circularStrokeCap != CircularStrokeCap.butt)
-                            ? widget.lineWidth / 2
-                            : 0,
+                        (widget.circularStrokeCap != CircularStrokeCap.butt) ? widget.lineWidth / 2 : 0,
                         (-widget.radius / 2 + widget.lineWidth / 2),
                       ),
                       child: widget.widgetIndicator,
@@ -310,6 +284,7 @@ class CirclePainter extends CustomPainter {
   final double lineWidth;
   final double backgroundWidth;
   final double progress;
+  final double progressOver;
   final double radius;
   final Color progressColor;
   final Color backgroundColor;
@@ -322,10 +297,13 @@ class CirclePainter extends CustomPainter {
   final MaskFilter maskFilter;
   final bool rotateLinearGradient;
 
+  final Paint _paintScale = Paint()..strokeWidth = 1;
+
   CirclePainter(
       {this.lineWidth,
       this.backgroundWidth,
       this.progress,
+        this.progressOver,
       @required this.radius,
       this.progressColor,
       this.backgroundColor,
@@ -380,7 +358,9 @@ class CirclePainter extends CustomPainter {
     final rectForArc = Rect.fromCircle(center: center, radius: radius);
     double startAngleFixedMargin = 1.0;
     if (arcType != null) {
-      if (arcType == ArcType.FULL) {
+      if (arcType == ArcType.CUSTOM) {
+        startAngleFixedMargin = 1 - (fixedStartAngle - 180).abs() * 2 / 360;
+      } else if (arcType == ArcType.FULL) {
         fixedStartAngle = 220;
         startAngleFixedMargin = 172 / fixedStartAngle;
       } else {
@@ -389,8 +369,9 @@ class CirclePainter extends CustomPainter {
       }
     }
     if (arcType == ArcType.HALF) {
-      canvas.drawArc(rectForArc, radians(-90.0 + fixedStartAngle),
-          radians(360 * startAngleFixedMargin), false, _paintBackground);
+      canvas.drawArc(rectForArc, radians(-90.0 + fixedStartAngle), radians(360 * startAngleFixedMargin), false, _paintBackground);
+    } else if (arcType == ArcType.CUSTOM) {
+      canvas.drawArc(rectForArc, radians(-90.0 + fixedStartAngle), radians(360 * startAngleFixedMargin), false, _paintBackground);
     } else {
       canvas.drawCircle(center, radius, _paintBackground);
     }
@@ -401,8 +382,7 @@ class CirclePainter extends CustomPainter {
     if (linearGradient != null) {
       if (rotateLinearGradient && progress > 0) {
         double correction = 0;
-        if (_paintLine.strokeCap == StrokeCap.round ||
-            _paintLine.strokeCap == StrokeCap.square) {
+        if (_paintLine.strokeCap == StrokeCap.round || _paintLine.strokeCap == StrokeCap.square) {
           if (reverse) {
             correction = math.atan(_paintLine.strokeWidth / 2 / radius);
           } else {
@@ -410,17 +390,12 @@ class CirclePainter extends CustomPainter {
           }
         }
         _paintLine.shader = SweepGradient(
-                transform: reverse
-                    ? GradientRotation(
-                        radians(-90 - progress + startAngle) - correction)
-                    : GradientRotation(
-                        radians(-90.0 + startAngle) - correction),
+                transform:
+                    reverse ? GradientRotation(radians(-90 - progress + startAngle) - correction) : GradientRotation(radians(-90.0 + startAngle) - correction),
                 startAngle: radians(0),
-                endAngle: radians(progress),
+                endAngle: radians(360),
                 tileMode: TileMode.clamp,
-                colors: reverse
-                    ? linearGradient.colors.reversed.toList()
-                    : linearGradient.colors)
+                colors: reverse ? linearGradient.colors.reversed.toList() : linearGradient.colors)
             .createShader(
           Rect.fromCircle(
             center: center,
@@ -437,19 +412,6 @@ class CirclePainter extends CustomPainter {
       }
     }
 
-    fixedStartAngle = startAngle;
-
-    startAngleFixedMargin = 1.0;
-    if (arcType != null) {
-      if (arcType == ArcType.FULL) {
-        fixedStartAngle = 220;
-        startAngleFixedMargin = 172 / fixedStartAngle;
-      } else {
-        fixedStartAngle = 270;
-        startAngleFixedMargin = 135 / fixedStartAngle;
-      }
-    }
-
     if (arcBackgroundColor != null) {
       canvas.drawArc(
         Rect.fromCircle(center: center, radius: radius),
@@ -460,9 +422,32 @@ class CirclePainter extends CustomPainter {
       );
     }
 
+    if (arcType == ArcType.CUSTOM) {
+      if(progressOver > 0) {
+        canvas.save();
+        var rect = RRect.fromRectAndRadius(Rect.fromCenter(center: Offset(center.dy, lineWidth + 5), width: 2, height: 3), Radius.circular(5.0));
+        canvas.translate(center.dx, center.dy);
+        canvas.rotate(radians(fixedStartAngle));
+        canvas.translate(-center.dx, -center.dy);
+        var count = 60;
+        var r = radians(360 * startAngleFixedMargin) / count;
+        for (var i = 0; i <= count; i++) {
+          if (progressOver >= i / count) {
+            _paintScale.color = _setColor(i, count);
+          } else {
+            _paintScale.color = backgroundColor;
+          }
+          canvas.drawRRect(rect, _paintScale);
+          canvas.translate(center.dx, center.dy);
+          canvas.rotate(r);
+          canvas.translate(-center.dx, -center.dy);
+        }
+        canvas.restore();
+      }
+    }
+
     if (reverse) {
-      final start =
-          radians(360 * startAngleFixedMargin - 90.0 + fixedStartAngle);
+      final start = radians(360 * startAngleFixedMargin - 90.0 + fixedStartAngle);
       final end = radians(-progress * startAngleFixedMargin);
       canvas.drawArc(
         Rect.fromCircle(
@@ -490,6 +475,17 @@ class CirclePainter extends CustomPainter {
     }
   }
 
+  final Color _o = const Color(0xff16A2FF);
+  final Color _o1 = const Color(0xff8DF7FF);
+  _setColor(int val,int mCount) {
+    double one = (255 + 255) / (mCount * 2 / 3);
+    int r = 0, g = 0, b = 0;
+    r = (_o.red + (_o1.red - _o.red) * val / mCount).toInt();
+    g = (_o.green + (_o1.green - _o.green) * val / mCount).toInt();
+    b = (_o.blue + (_o1.blue - _o.blue) * val / mCount).toInt();
+    int d =  -val;
+    return Color.fromRGBO(r,g,b, 1.0);
+  }
   @override
   bool shouldRepaint(CustomPainter oldDelegate) {
     return true;