Как создать этот индикатор прогресса? Особенно я не знаю, как сделать анимацию потока

#flutter #dart #progress-bar #flutter-animation

#трепетать #дротик #индикатор выполнения #флаттер-анимация

Вопрос:

введите описание изображения здесь

Я хочу знать, как сделать эту анимацию потока. Кто-нибудь знает?

Ответ №1:

Я пробовал только с виджетом, но у меня ничего не получилось. Поэтому я выбираю краску на заказ. Взгляните на мой код.

 import 'dart:async';  import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart';  class MyAnimatedLoading extends StatefulWidget {  final Offset offsetSpeed;  final Listlt;MaterialColorgt; colors;  final double width;  final double height;   const MyAnimatedLoading(  {Key? key,  required this.offsetSpeed,  required this.colors,  required this.width,  required this.height})  : super(key: key);   @override  Statelt;MyAnimatedLoadinggt; createState() =gt; _MyAnimatedLoadingState(); }  class _MyAnimatedLoadingState extends Statelt;MyAnimatedLoadinggt; {  late Listlt;Nodegt; nodes;  late double width;   @override  void initState() {  super.initState();  width = widget.width / (widget.colors.length);   nodes = List.generate(widget.colors.length, (index) {  return Node(  rect: Rect.fromCenter(  center: Offset(index * width   width / 2, widget.height / 2),  width: width,  height: widget.height),  color: widget.colors[index],  );  });   Listlt;Nodegt; tempNodes = lt;Nodegt;[];  for (int i = -widget.colors.length; i lt;= -1; i  ) {  tempNodes.add(Node(  rect: Rect.fromCenter(  center: Offset(i * width   width / 2, widget.height / 2),  width: width,  height: widget.height),  color: widget.colors.first,  ));  }   for (int i = 0; i lt; tempNodes.length; i  ) {  tempNodes[i].color = widget.colors[i];  }   nodes.addAll(tempNodes);   Timer.periodic(const Duration(milliseconds: 20), (timer) {  if (mounted) {  setState(() {});  }  });  }   @override  Widget build(BuildContext context) {  _calculateNewPositions();  return ClipRRect(  clipBehavior: Clip.hardEdge,  borderRadius: const BorderRadius.all(Radius.circular(25)),  child: CustomPaint(  size: Size(widget.width, widget.height),  painter: MyCustomPaint(nodes: nodes),  ),  );  }   void _calculateNewPositions() {  for (final node in nodes) {  final offset = node.rect.center;   if (offset.dx - width / 2 gt;= widget.width) {  node.rect = Rect.fromCenter(  center: Offset(  (-width / 2) * (widget.colors.length * 2)   width / 2,  widget.height / 2)    widget.offsetSpeed,  width: width,  height: widget.height);  } else {  node.rect = Rect.fromCenter(  center: offset   widget.offsetSpeed,  width: width,  height: widget.height);  }  }  } }  class Node {  Rect rect;  Color color;   Node({required this.rect, required this.color});   @override  String toString() {  return 'Node{rect: $rect, color: $color}n';  } }  class MyCustomPaint extends CustomPainter {  Listlt;Nodegt; nodes;   MyCustomPaint({required this.nodes});   @override  void paint(Canvas canvas, Size size) {  for (int i = 0; i lt; nodes.length; i  ) {  canvas.drawRect(nodes[i].rect, Paint()..color = nodes[i].color);  }  }   @override  bool shouldRepaint(covariant CustomPainter oldDelegate) {  return true;  } }    

Это не совсем та же анимация, но это хорошая отправная точка

 const MyAnimatedLoading(  offsetSpeed: Offset(1, 0),  width: 220,  height: 20,  colors: [  Colors.yellow,  Colors.deepOrange,  Colors.red,  Colors.blue,  Colors.green,  ],  )