#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, ], )