簡體   English   中英

Flutter 圓形進度指示器-可重復-定制畫家

[英]Flutter circular progress indicator - repeatable-Custom painter

我想創造這樣的東西:想要實現

我已經做到了:到現在為止

我正在努力在這個圓形進度條的 state 處添加垂直線,就像尾隨處的線一樣。

import 'dart:math';

import 'package:flutter/material.dart';

class LoaderPaint extends CustomPainter {
  final double percentage;
  LoaderPaint({
    required this.percentage,
  });

  deg2Rand(double deg) => deg * pi / 180;

  @override
  void paint(Canvas canvas, Size size) {
    final midOffset = Offset(size.width / 2, size.height / 2);

    final paint = Paint()
      ..strokeCap = StrokeCap.round
      ..color = Colors.white
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2;

    canvas.drawLine(
      Offset(midOffset.dy, 10),
      Offset(midOffset.dy,-10),
      paint,
    );
    canvas.drawArc(
      Rect.fromCenter(center: midOffset, width: size.width, height: size.height),
      deg2Rand(-90),
      deg2Rand(360 * percentage),
      false,
      paint,
    );

  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}
  1. 使用此stackoverflow 答案中的公式計算行的末尾 position。 由於我們從 -90 度開始角度,因此我們必須將其從 sweepAngle 中移開。

  2. 使用此答案中的公式計算直線末端 position 前后 10 個單位的點,插入圓心和直線末端 position。

  3. canvas.drawLine畫線

以下是更新后的LoaderPaint class 與這些更改后的樣子:

class LoaderPaint extends CustomPainter {
  final double percentage;
  const LoaderPaint({
    required this.percentage,
  });

  deg2Rand(double deg) => deg * pi / 180;

  @override
  void paint(Canvas canvas, Size size) {
    final radius = size.width / 2;
    final sweepAngle = deg2Rand(360 * percentage);
    final theta = deg2Rand(-90) + sweepAngle;
    
    final midOffset = Offset(radius, radius);
    final endOffset = Offset(radius + radius * cos(theta), radius + radius * sin(theta));
    
    final midEndDiff = sqrt(pow(endOffset.dx - midOffset.dx, 2) + pow(endOffset.dy - midOffset.dy, 2));

    final paint = Paint()
      ..strokeCap = StrokeCap.round
      ..color = Colors.white
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2;

    canvas.drawLine(
      Offset(midOffset.dy, 10),
      Offset(midOffset.dy,-10),
      paint,
    );
    canvas.drawArc(
      Rect.fromCenter(center: midOffset, width: size.width, height: size.height),
      deg2Rand(-90),
      sweepAngle,
      false,
      paint,
    );
    canvas.drawLine(
      Offset(endOffset.dx + (10/midEndDiff) * (endOffset.dx - midOffset.dx), endOffset.dy + (10/midEndDiff) * (endOffset.dy - midOffset.dy)),
      Offset(endOffset.dx - (10/midEndDiff) * (endOffset.dx - midOffset.dx), endOffset.dy - (10/midEndDiff) * (endOffset.dy - midOffset.dy)),
      paint,
    );

  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

這個 dartpad顯示它工作正常。 您可以輕松更改百分比以查看它在各個角度的工作情況。

您必須記住,這僅在CustomPaint小部件的寬度和高度完全相同的情況下才有效,但是如果寬度和高度不同,您的沒有端蓋的示例也會中斷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM