Skip to content

Commit c6dc38d

Browse files
committed
feat: add CustomMaterialIndicator.adaptive constructor
1 parent ae78af4 commit c6dc38d

File tree

3 files changed

+75
-12
lines changed

3 files changed

+75
-12
lines changed

lib/src/custom_refresh_indicator.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ class CustomRefreshIndicator extends StatefulWidget {
154154
return notification.depth == 0;
155155
}
156156

157-
CustomRefreshIndicator({
157+
const CustomRefreshIndicator({
158158
super.key,
159159
required this.child,
160160
required this.onRefresh,

lib/src/indicator_controller.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ class IndicatorController extends Animation<double>
235235
///
236236
/// - [min] represents the smallest value the animation can have.
237237
/// - [max] represents the largest value the animation can have.
238-
///
238+
///
239239
/// If instead of transforming the entire range of controller values, you want to use only a specific range, see the [clamp] method.
240240
Animation<double> transform(double min, double max) => TransformedAnimation(
241241
parent: this,

lib/src/widgets/custom_material_indicator.dart

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:custom_refresh_indicator/custom_refresh_indicator.dart';
22
import 'package:custom_refresh_indicator/src/custom_refresh_indicator.dart';
3+
import 'package:flutter/cupertino.dart';
34
import 'package:flutter/foundation.dart';
45
import 'package:flutter/material.dart';
56

@@ -111,6 +112,9 @@ class CustomMaterialIndicator extends StatefulWidget {
111112
/// [ColorScheme.primary] by default.
112113
final Color? color;
113114

115+
/// when true, the appropriate indicator should be selected depending on the platform.
116+
final bool _isAdaptive;
117+
114118
const CustomMaterialIndicator({
115119
super.key,
116120
required this.child,
@@ -140,7 +144,40 @@ class CustomMaterialIndicator extends StatefulWidget {
140144
(color == null && semanticsValue == null && semanticsLabel == null && strokeWidth == null),
141145
'When a custom indicatorBuilder is provided, the parameters color, semanticsValue, semanticsLabel and strokeWidth are unused and can be safely removed.',
142146
),
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;
144181

145182
static Widget _defaultBuilder(BuildContext context, Widget child, IndicatorController controller) => child;
146183

@@ -182,7 +219,7 @@ class _CustomMaterialIndicatorState extends State<CustomMaterialIndicator> {
182219
);
183220
}
184221

185-
Widget _defaultIndicatorBuilder(BuildContext context, IndicatorController controller) {
222+
Widget _defaultMaterialIndicatorBuilder(BuildContext context, IndicatorController controller) {
186223
final bool showIndeterminateIndicator = controller.isLoading || controller.isComplete || controller.isFinalizing;
187224

188225
return RefreshProgressIndicator(
@@ -195,6 +232,12 @@ class _CustomMaterialIndicatorState extends State<CustomMaterialIndicator> {
195232
);
196233
}
197234

235+
Widget _defaultCupertinoIndicatorBuilder(BuildContext context, IndicatorController controller) {
236+
return CupertinoActivityIndicator(
237+
color: widget.color,
238+
);
239+
}
240+
198241
late Animation<double> _valueAnimation;
199242
late Animation<Color?> _colorAnimation;
200243
late Color _indicatorColor;
@@ -242,7 +285,25 @@ class _CustomMaterialIndicatorState extends State<CustomMaterialIndicator> {
242285

243286
@override
244287
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);
246307

247308
return CustomRefreshIndicator(
248309
autoRebuild: false,
@@ -269,13 +330,15 @@ class _CustomMaterialIndicatorState extends State<CustomMaterialIndicator> {
269330
width: 41,
270331
height: 41,
271332
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,
279342
);
280343
}
281344

0 commit comments

Comments
 (0)