1
1
import 'package:custom_refresh_indicator/custom_refresh_indicator.dart' ;
2
2
import 'package:custom_refresh_indicator/src/custom_refresh_indicator.dart' ;
3
+ import 'package:flutter/cupertino.dart' ;
3
4
import 'package:flutter/foundation.dart' ;
4
5
import 'package:flutter/material.dart' ;
5
6
@@ -111,6 +112,9 @@ class CustomMaterialIndicator extends StatefulWidget {
111
112
/// [ColorScheme.primary] by default.
112
113
final Color ? color;
113
114
115
+ /// when true, the appropriate indicator should be selected depending on the platform.
116
+ final bool _isAdaptive;
117
+
114
118
const CustomMaterialIndicator ({
115
119
super .key,
116
120
required this .child,
@@ -140,7 +144,40 @@ class CustomMaterialIndicator extends StatefulWidget {
140
144
(color == null && semanticsValue == null && semanticsLabel == null && strokeWidth == null ),
141
145
'When a custom indicatorBuilder is provided, the parameters color, semanticsValue, semanticsLabel and strokeWidth are unused and can be safely removed.' ,
142
146
),
143
- strokeWidth = strokeWidth ?? RefreshProgressIndicator .defaultStrokeWidth;
147
+ strokeWidth = strokeWidth ?? RefreshProgressIndicator .defaultStrokeWidth,
148
+ _isAdaptive = false ;
149
+
150
+ const CustomMaterialIndicator .adaptive ({
151
+ super .key,
152
+ required this .child,
153
+ required this .onRefresh,
154
+ this .indicatorBuilder,
155
+ this .scrollableBuilder = _defaultBuilder,
156
+ this .notificationPredicate = CustomRefreshIndicator .defaultScrollNotificationPredicate,
157
+ this .backgroundColor,
158
+ this .displacement = 40.0 ,
159
+ this .edgeOffset = 0.0 ,
160
+ this .elevation = 2.0 ,
161
+ this .clipBehavior = Clip .none,
162
+ this .autoRebuild = true ,
163
+ this .trigger = IndicatorTrigger .leadingEdge,
164
+ this .triggerMode = IndicatorTriggerMode .onEdge,
165
+ this .controller,
166
+ this .durations = const RefreshIndicatorDurations (),
167
+ this .onStateChanged,
168
+ this .leadingScrollIndicatorVisible = false ,
169
+ this .trailingScrollIndicatorVisible = true ,
170
+ double ? strokeWidth,
171
+ this .semanticsLabel,
172
+ this .semanticsValue,
173
+ this .color,
174
+ }) : assert (
175
+ indicatorBuilder == null ||
176
+ (color == null && semanticsValue == null && semanticsLabel == null && strokeWidth == null ),
177
+ 'When a custom indicatorBuilder is provided, the parameters color, semanticsValue, semanticsLabel and strokeWidth are unused and can be safely removed.' ,
178
+ ),
179
+ strokeWidth = strokeWidth ?? RefreshProgressIndicator .defaultStrokeWidth,
180
+ _isAdaptive = true ;
144
181
145
182
static Widget _defaultBuilder (BuildContext context, Widget child, IndicatorController controller) => child;
146
183
@@ -182,7 +219,7 @@ class _CustomMaterialIndicatorState extends State<CustomMaterialIndicator> {
182
219
);
183
220
}
184
221
185
- Widget _defaultIndicatorBuilder (BuildContext context, IndicatorController controller) {
222
+ Widget _defaultMaterialIndicatorBuilder (BuildContext context, IndicatorController controller) {
186
223
final bool showIndeterminateIndicator = controller.isLoading || controller.isComplete || controller.isFinalizing;
187
224
188
225
return RefreshProgressIndicator (
@@ -195,6 +232,12 @@ class _CustomMaterialIndicatorState extends State<CustomMaterialIndicator> {
195
232
);
196
233
}
197
234
235
+ Widget _defaultCupertinoIndicatorBuilder (BuildContext context, IndicatorController controller) {
236
+ return CupertinoActivityIndicator (
237
+ color: widget.color,
238
+ );
239
+ }
240
+
198
241
late Animation <double > _valueAnimation;
199
242
late Animation <Color ?> _colorAnimation;
200
243
late Color _indicatorColor;
@@ -242,7 +285,25 @@ class _CustomMaterialIndicatorState extends State<CustomMaterialIndicator> {
242
285
243
286
@override
244
287
Widget build (BuildContext context) {
245
- final indicatorBuilder = widget.indicatorBuilder ?? _defaultIndicatorBuilder;
288
+ bool useMaterial = true ;
289
+ if (widget._isAdaptive) {
290
+ final ThemeData theme = Theme .of (context);
291
+ switch (theme.platform) {
292
+ case TargetPlatform .android:
293
+ case TargetPlatform .fuchsia:
294
+ case TargetPlatform .linux:
295
+ case TargetPlatform .windows:
296
+ useMaterial = true ;
297
+ break ;
298
+ case TargetPlatform .iOS:
299
+ case TargetPlatform .macOS:
300
+ useMaterial = false ;
301
+ break ;
302
+ }
303
+ }
304
+
305
+ final MaterialIndicatorBuilder indicatorBuilder =
306
+ widget.indicatorBuilder ?? (useMaterial ? _defaultMaterialIndicatorBuilder : _defaultCupertinoIndicatorBuilder);
246
307
247
308
return CustomRefreshIndicator (
248
309
autoRebuild: false ,
@@ -269,13 +330,15 @@ class _CustomMaterialIndicatorState extends State<CustomMaterialIndicator> {
269
330
width: 41 ,
270
331
height: 41 ,
271
332
margin: const EdgeInsets .all (4.0 ),
272
- child: Material (
273
- type: MaterialType .circle,
274
- clipBehavior: widget.clipBehavior,
275
- color: _backgroundColor,
276
- elevation: widget.elevation,
277
- child: indicator,
278
- ),
333
+ child: useMaterial
334
+ ? Material (
335
+ type: MaterialType .circle,
336
+ clipBehavior: widget.clipBehavior,
337
+ color: _backgroundColor,
338
+ elevation: widget.elevation,
339
+ child: indicator,
340
+ )
341
+ : indicator,
279
342
);
280
343
}
281
344
0 commit comments