Skip to content

Commit 2de1130

Browse files
author
Kamil Klyta
committed
Add material indicator delegate to readme
1 parent 2db35ea commit 2de1130

File tree

4 files changed

+98
-79
lines changed

4 files changed

+98
-79
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,28 @@ CustomRefreshIndicator(
4444
)
4545
```
4646

47+
## MaterialIndicatorDelegate
48+
If you just want to replace the content of the material indicator, you can use *MaterialIndicatorDelegate*, which builds a material container.
49+
```dart
50+
CustomRefreshIndicator(
51+
/// Scrollable widget
52+
child: ListView.builder(
53+
itemBuilder: (BuildContext context, int index) => Text(index.toString()),
54+
),
55+
/// delegate with configuration
56+
builder: MaterialIndicatorDelegate(
57+
builder: (context, controller) {
58+
return Icon(
59+
Icons.ac_unit,
60+
color: Colors.black,
61+
size: 30,
62+
);
63+
},
64+
),
65+
onRefresh: myAsyncRefreshMethod,
66+
)
67+
```
68+
4769
# Examples
4870

4971
Almost all of these examples are available in the example application.

example/lib/indicators/simple_indicator.dart

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
import 'package:custom_refresh_indicator/custom_refresh_indicator.dart';
2-
import 'package:example/utils/infinite_rotation.dart';
32
import 'package:flutter/material.dart';
43

54
import 'custom_indicator.dart';
65

76
final simpleIndicator = CustomIndicatorConfig(
87
builder: MaterialIndicatorDelegate(
98
builder: (context, controller) {
10-
return InfiniteRatation(
11-
running: controller.isLoading,
12-
child: Icon(
13-
Icons.ac_unit,
14-
color: Theme.of(context).colorScheme.primary,
15-
size: 30,
16-
),
9+
return Icon(
10+
Icons.ac_unit,
11+
color: Theme.of(context).colorScheme.primary,
12+
size: 30,
1713
);
1814
},
1915
),
@@ -22,13 +18,10 @@ final simpleIndicator = CustomIndicatorConfig(
2218
final simpleIndicatorWithOpacity = CustomIndicatorConfig(
2319
builder: MaterialIndicatorDelegate(
2420
builder: (context, controller) {
25-
return InfiniteRatation(
26-
running: controller.isLoading,
27-
child: Icon(
28-
Icons.ac_unit,
29-
color: Theme.of(context).colorScheme.primary,
30-
size: 30,
31-
),
21+
return Icon(
22+
Icons.ac_unit,
23+
color: Theme.of(context).colorScheme.primary,
24+
size: 30,
3225
);
3326
},
3427
scrollableBuilder: (context, child, controller) {

example/lib/utils/infinite_rotation.dart

Lines changed: 0 additions & 63 deletions
This file was deleted.

lib/src/delegates/material_indicator_delegate.dart

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,16 @@ class MaterialIndicatorDelegate extends IndicatorBuilderDelegate {
3838
/// Builds the scrollable.
3939
final IndicatorBuilder scrollableBuilder;
4040

41+
/// When set to *true*, the indicator will rotate in the [IndicatorState.loading] state.
42+
final bool withRotation;
43+
4144
const MaterialIndicatorDelegate({
4245
required this.builder,
4346
this.scrollableBuilder = _defaultBuilder,
4447
this.backgroundColor,
4548
this.displacement = 40.0,
4649
this.edgeOffset = 0.0,
50+
this.withRotation = true,
4751
});
4852

4953
static Widget _defaultBuilder(
@@ -82,7 +86,10 @@ class MaterialIndicatorDelegate extends IndicatorBuilderDelegate {
8286
type: MaterialType.circle,
8387
color: backgroundColor,
8488
elevation: 2.0,
85-
child: builder(context, controller),
89+
child: _InfiniteRotation(
90+
running: withRotation && controller.isLoading,
91+
child: builder(context, controller),
92+
),
8693
),
8794
),
8895
),
@@ -190,3 +197,63 @@ class _PositionedIndicatorContainer extends StatelessWidget {
190197
);
191198
}
192199
}
200+
201+
class _InfiniteRotation extends StatefulWidget {
202+
final Widget? child;
203+
final bool running;
204+
205+
const _InfiniteRotation({
206+
required this.child,
207+
required this.running,
208+
Key? key,
209+
}) : super(key: key);
210+
@override
211+
_InfiniteRotationState createState() => _InfiniteRotationState();
212+
}
213+
214+
class _InfiniteRotationState extends State<_InfiniteRotation>
215+
with SingleTickerProviderStateMixin {
216+
late AnimationController _rotationController;
217+
218+
@override
219+
void didUpdateWidget(_InfiniteRotation oldWidget) {
220+
if (oldWidget.running != widget.running) {
221+
if (widget.running) {
222+
_startAnimation();
223+
} else {
224+
_rotationController
225+
..stop()
226+
..value = 0.0;
227+
}
228+
}
229+
super.didUpdateWidget(oldWidget);
230+
}
231+
232+
@override
233+
void initState() {
234+
_rotationController = AnimationController(
235+
duration: const Duration(milliseconds: 750),
236+
vsync: this,
237+
);
238+
239+
if (widget.running) {
240+
_startAnimation();
241+
}
242+
243+
super.initState();
244+
}
245+
246+
@override
247+
void dispose() {
248+
_rotationController.dispose();
249+
super.dispose();
250+
}
251+
252+
void _startAnimation() {
253+
_rotationController.repeat();
254+
}
255+
256+
@override
257+
Widget build(BuildContext context) =>
258+
RotationTransition(turns: _rotationController, child: widget.child);
259+
}

0 commit comments

Comments
 (0)