CircularProgressIndicator с разделителями для этапов / шагов (например, 1/3, 2/3, 3/3) - PullRequest
0 голосов
/ 28 апреля 2020

Hello Flutter Community,

Я хочу создать этот пользовательский CircularProgressIndicator:

CircularProgressIndicator with steps

Для текста, который я создал стек:

Stack(
  children: [
    Container(
      height: 75.0,
      width: 75.0,
      child: CircularProgressIndicator(
        strokeWidth: 6.0,
        backgroundColor: Color.fromRGBO(230, 230, 230, 1.0),
        valueColor: AlwaysStoppedAnimation<Color>(
            Color.fromRGBO(252, 90, 73, 1.0)),
        value: 0.4,
      ),
    ),
    Positioned(
      child: Container(
        height: 75.0,
        width: 75.0,
        child: Center(
          child: Text("2 of 6"),
        ),
      ),
    ),
  ],
),

Я думал о том, чтобы нарисовать шесть линий с поворотом на + 60 ° (количество шагов / 360 °) от центра к концу, но я не знаю, как это сделать.

enter image description here

Есть ли элегантный способ добиться этого?

Приветствия из Германии

Редактировать (1): У меня есть нашел решение, но меня это не устраивает:



Stack(
  children: [
    Container(
      height: 75.0,
      width: 75.0,
      child: CircularProgressIndicator(
        strokeWidth: 6.0,
        backgroundColor: Color.fromRGBO(230, 230, 230, 1.0),
        valueColor: AlwaysStoppedAnimation<Color>(
            Color.fromRGBO(252, 90, 73, 1.0)),
        value: 2/6,
      ),
    ),
    Positioned(
      height: 75.0,
      width: 75.0,
      child: Center(
        child: CustomPaint(
          painter: DrawRadialLines(
              amount: 6,
              thickness: 4,
              length: 75,
              color: Colors.white),
        ),
      ),
    ),
    Positioned(
      child: Container(
        height: 75.0,
        width: 75.0,
        child: Center(
          child: Text("2 of 6"),
        ),
      ),
    ),
  ],
),

И этот класс DrawRadialLines:

class DrawRadialLines extends CustomPainter {
  Paint _paint;
  final double thickness;
  final double amount;
  final double length;
  final Color color;
  DrawRadialLines({this.thickness, this.amount, this.length, this.color}) {
    _paint = Paint()
      ..color = this.color
      ..strokeWidth = this.thickness
      ..strokeCap = StrokeCap.round;
  }

  @override
  void paint(Canvas canvas, Size size) {
    final double _strokeThickness = thickness;
    final double _rotationPerLine = 360 / amount;
    final double _length = length/2 + _strokeThickness;
    canvas.rotate(-90 * (3.1415926 / 180)); //rotate so it will start from top
    for (int i = 0; i < amount; i++) {
      canvas.rotate(_rotationPerLine * (3.1415926 / 180));
      canvas.drawLine(Offset(0, 0.0), Offset(_length, 0.0), _paint);
    }
  }

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

выведет это: enter image description here

Но есть ли более элегантное решение?

1 Ответ

1 голос
/ 28 апреля 2020

Вы можете добавить разделители к новому Stack следующим образом:

Сначала добавьте AlignmentDirectional.center в свой стек и добавьте новый стек в существующий стек

Stack(
  alignment: AlignmentDirectional.center,
  children: [
    Container(
      height: 75.0,
      width: 75.0,
      child: CircularProgressIndicator(
        strokeWidth: 6.0,
        backgroundColor: Color.fromRGBO(230, 230, 230, 1.0),
        valueColor: AlwaysStoppedAnimation<Color>(Color.fromRGBO(252, 90, 73, 1.0)),
        value: 0.4,
      ),
    ),
    Positioned(
      child: Container(
        height: 75.0,
        width: 75.0,
        child: Center(
          child: Text("2 of 6"),
        ),
      ),
    ),
    Stack(
      children: buildSeparators(6),
    ),
  ],
),

и есть метод buildSeparators

List<Widget> buildSeparators(int nbSeparators) {
  var sep = <Widget>[];
  for (var i = 0; i < nbSeparators; i++) {
    sep.add(
      Transform.rotate(
        angle: i * 1 / nbSeparators * 2 * pi,
        child: Container(
          width: 10,
          height: 81,
          child: Column(
            children: <Widget>[
              Container(
                width: 8,
                height: 10,
                color: Colors.white,
              )
            ],
          ),
        ),
      ),
    );
  }
  return sep;
}

Это можно улучшить, но это идея

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...