"Fossies" - the Fresh Open Source Software Archive 
Member "flutter-3.7.1/packages/flutter/lib/src/cupertino/activity_indicator.dart" (1 Feb 2023, 5995 Bytes) of package /linux/misc/flutter-3.7.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Dart source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 // Copyright 2014 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 import 'dart:math' as math;
6
7 import 'package:flutter/widgets.dart';
8
9 import 'colors.dart';
10
11 const double _kDefaultIndicatorRadius = 10.0;
12
13 // Extracted from iOS 13.2 Beta.
14 const Color _kActiveTickColor = CupertinoDynamicColor.withBrightness(
15 color: Color(0xFF3C3C44),
16 darkColor: Color(0xFFEBEBF5),
17 );
18
19 /// An iOS-style activity indicator that spins clockwise.
20 ///
21 /// {@youtube 560 315 https://www.youtube.com/watch?v=AENVH-ZqKDQ}
22 ///
23 /// {@tool dartpad}
24 /// This example shows how [CupertinoActivityIndicator] can be customized.
25 ///
26 /// ** See code in examples/api/lib/cupertino/activity_indicator/cupertino_activity_indicator.0.dart **
27 /// {@end-tool}
28 ///
29 /// See also:
30 ///
31 /// * <https://developer.apple.com/ios/human-interface-guidelines/controls/progress-indicators/#activity-indicators>
32 class CupertinoActivityIndicator extends StatefulWidget {
33 /// Creates an iOS-style activity indicator that spins clockwise.
34 const CupertinoActivityIndicator({
35 super.key,
36 this.color,
37 this.animating = true,
38 this.radius = _kDefaultIndicatorRadius,
39 }) : assert(animating != null),
40 assert(radius != null),
41 assert(radius > 0.0),
42 progress = 1.0;
43
44 /// Creates a non-animated iOS-style activity indicator that displays
45 /// a partial count of ticks based on the value of [progress].
46 ///
47 /// When provided, the value of [progress] must be between 0.0 (zero ticks
48 /// will be shown) and 1.0 (all ticks will be shown) inclusive. Defaults
49 /// to 1.0.
50 const CupertinoActivityIndicator.partiallyRevealed({
51 super.key,
52 this.color,
53 this.radius = _kDefaultIndicatorRadius,
54 this.progress = 1.0,
55 }) : assert(radius != null),
56 assert(radius > 0.0),
57 assert(progress != null),
58 assert(progress >= 0.0),
59 assert(progress <= 1.0),
60 animating = false;
61
62 /// Color of the activity indicator.
63 ///
64 /// Defaults to color extracted from native iOS.
65 final Color? color;
66
67 /// Whether the activity indicator is running its animation.
68 ///
69 /// Defaults to true.
70 final bool animating;
71
72 /// Radius of the spinner widget.
73 ///
74 /// Defaults to 10px. Must be positive and cannot be null.
75 final double radius;
76
77 /// Determines the percentage of spinner ticks that will be shown. Typical usage would
78 /// display all ticks, however, this allows for more fine-grained control such as
79 /// during pull-to-refresh when the drag-down action shows one tick at a time as
80 /// the user continues to drag down.
81 ///
82 /// Defaults to 1.0. Must be between 0.0 and 1.0 inclusive, and cannot be null.
83 final double progress;
84
85 @override
86 State<CupertinoActivityIndicator> createState() => _CupertinoActivityIndicatorState();
87 }
88
89 class _CupertinoActivityIndicatorState extends State<CupertinoActivityIndicator>
90 with SingleTickerProviderStateMixin {
91 late AnimationController _controller;
92
93 @override
94 void initState() {
95 super.initState();
96 _controller = AnimationController(
97 duration: const Duration(seconds: 1),
98 vsync: this,
99 );
100
101 if (widget.animating) {
102 _controller.repeat();
103 }
104 }
105
106 @override
107 void didUpdateWidget(CupertinoActivityIndicator oldWidget) {
108 super.didUpdateWidget(oldWidget);
109 if (widget.animating != oldWidget.animating) {
110 if (widget.animating) {
111 _controller.repeat();
112 } else {
113 _controller.stop();
114 }
115 }
116 }
117
118 @override
119 void dispose() {
120 _controller.dispose();
121 super.dispose();
122 }
123
124 @override
125 Widget build(BuildContext context) {
126 return SizedBox(
127 height: widget.radius * 2,
128 width: widget.radius * 2,
129 child: CustomPaint(
130 painter: _CupertinoActivityIndicatorPainter(
131 position: _controller,
132 activeColor: widget.color ?? CupertinoDynamicColor.resolve(_kActiveTickColor, context),
133 radius: widget.radius,
134 progress: widget.progress,
135 ),
136 ),
137 );
138 }
139 }
140
141 const double _kTwoPI = math.pi * 2.0;
142
143 /// Alpha values extracted from the native component (for both dark and light mode) to
144 /// draw the spinning ticks.
145 const List<int> _kAlphaValues = <int>[
146 47,
147 47,
148 47,
149 47,
150 72,
151 97,
152 122,
153 147,
154 ];
155
156 /// The alpha value that is used to draw the partially revealed ticks.
157 const int _partiallyRevealedAlpha = 147;
158
159 class _CupertinoActivityIndicatorPainter extends CustomPainter {
160 _CupertinoActivityIndicatorPainter({
161 required this.position,
162 required this.activeColor,
163 required this.radius,
164 required this.progress,
165 }) : tickFundamentalRRect = RRect.fromLTRBXY(
166 -radius / _kDefaultIndicatorRadius,
167 -radius / 3.0,
168 radius / _kDefaultIndicatorRadius,
169 -radius,
170 radius / _kDefaultIndicatorRadius,
171 radius / _kDefaultIndicatorRadius,
172 ),
173 super(repaint: position);
174
175 final Animation<double> position;
176 final Color activeColor;
177 final double radius;
178 final double progress;
179
180 final RRect tickFundamentalRRect;
181
182 @override
183 void paint(Canvas canvas, Size size) {
184 final Paint paint = Paint();
185 final int tickCount = _kAlphaValues.length;
186
187 canvas.save();
188 canvas.translate(size.width / 2.0, size.height / 2.0);
189
190 final int activeTick = (tickCount * position.value).floor();
191
192 for (int i = 0; i < tickCount * progress; ++i) {
193 final int t = (i - activeTick) % tickCount;
194 paint.color = activeColor
195 .withAlpha(progress < 1 ? _partiallyRevealedAlpha : _kAlphaValues[t]);
196 canvas.drawRRect(tickFundamentalRRect, paint);
197 canvas.rotate(_kTwoPI / tickCount);
198 }
199
200 canvas.restore();
201 }
202
203 @override
204 bool shouldRepaint(_CupertinoActivityIndicatorPainter oldPainter) {
205 return oldPainter.position != position ||
206 oldPainter.activeColor != activeColor ||
207 oldPainter.progress != progress;
208 }
209 }