Skip to content

Commit 1330570

Browse files
author
Kamil Klyta
committed
Update readme
1 parent b104ca5 commit 1330570

File tree

5 files changed

+184
-97
lines changed

5 files changed

+184
-97
lines changed

README.md

Lines changed: 131 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,19 @@
33

44
[![Tests](https://github.com/gonuit/flutter-custom-refresh-indicator/actions/workflows/test.yml/badge.svg)](https://github.com/gonuit/flutter-custom-refresh-indicator/actions/workflows/test.yml)
55

6-
A flutter package that allows you to easily create a custom refresh indicator widget.
6+
Create your own custom refresh indicator widget in the blink of an eye!
77

88
### **TLDR; [ONLINE DEMO](https://custom-refresh-indicator.klyta.it)**!
99

1010
---
1111

12-
# QUICK START
12+
## QUICK START
1313

1414
```dart
1515
CustomRefreshIndicator(
1616
/// Scrollable widget
1717
child: ListView.builder(
18-
itemBuilder: (BuildContext context, int index) => Container(
19-
child: Text(index.toString()),
20-
height: 100,
21-
),
18+
itemBuilder: (BuildContext context, int index) => Text(index.toString()),
2219
),
2320
/// The function that builds the indicator
2421
builder: (
@@ -29,14 +26,14 @@ CustomRefreshIndicator(
2926
/// TODO: Implement your own refresh indicator
3027
return Stack(
3128
children: <Widget>[
32-
/// Your indicator implementation
33-
return MyIndicator(value: controller.value, loading: controller.state.isLoading);
34-
35-
/// Scrollable widget that was provided as [child] argument
29+
/// The scroll widget that was passed as the [child] argument.
3630
///
3731
/// TIP:
38-
/// You can also wrap [child] with [Transform] widget to also a animate list transform (see example app)
32+
/// You can also wrap [child] with the [Transform] widget to also animate the list transformation (see the example app).
3933
child,
34+
35+
/// Your indicator implementation
36+
return MyIndicator(value: controller.value, loading: controller.state.isLoading);
4037
],
4138
);
4239
}
@@ -65,14 +62,27 @@ Almost all of these examples are available in the example application.
6562

6663
# Documentation
6764

68-
## CustomRefreshIndicator widget
65+
## CustomRefreshIndicator
6966

7067
The _CustomRefreshIndicator_ widget provides an absolute minimum functionality that allows you to create and set your own custom indicators.
7168

69+
### child (Widget)
70+
The widget tree that contains scrollable widget (eg. *ListView*).
71+
### builder (IndicatorBuilder)
72+
Function that builds the custom refresh indicator.
73+
74+
### onRefresh (AsyncCallback)
75+
A function that is called when the user drags the refresh indicator far enough to trigger a "pull to refresh" action.
76+
77+
### controller (IndicatorController?)
78+
The indicator controller stores all the data related to the refresh indicator widget. It will be passed as the third argument to the *builder* function.
79+
80+
If not specified, it will be created by the *CustomRefreshIndicator* widget.
81+
7282
### onStateChanged
7383

74-
The _onStateChanged_ callback is called everytime _IndicatorState_ has been changed.
75-
This is a convenient place for tracking indicator state changes. For a reference take a look at the [example check mark indicator widget](example/lib/indicators/check_mark_indicator.dart).
84+
The _onStateChanged_ function is called whenever _IndicatorState_ has changed.
85+
This is a convenient way to track changes in the state of the indicator. For reference, take a look at [example checkmark indicator widget](example/lib/indicators/check_mark_indicator.dart).
7686

7787
Example usage:
7888

@@ -91,28 +101,122 @@ CustomRefreshIndicator(
91101
// ...
92102
)
93103
```
104+
### indicatorCancelDuration (Duration)
105+
Duration of hiding the indicator when dragging was stopped before the indicator was armed (the *onRefresh* callback was not called).
106+
107+
The default is 300 milliseconds.
108+
### indicatorSettleDuration (Duration)
109+
The time of settling the pointer on the target location after releasing the pointer in the armed state. During this process, the value of the indicator decreases from its current value, which can be greater than or equal to *1.0* but less or equal to *1.5*, to a target value of *1.0*.
110+
111+
The default is 150 milliseconds.
94112

95-
## IndicatorController
113+
### indicatorFinalizeDuration (Duration)
114+
Duration of hiding the pointer after the *onRefresh* function completes.
115+
116+
During this time, the value of the controller decreases from *1.0* to *0.0* with a state set to *IndicatorState.finalizing*.
117+
118+
The default is 100 milliseconds.
96119

97-
### Controller state and value changes.
120+
### completeStateDuration (Duration?)
121+
The duration the indicator remains at value *1.0* and the *IndicatorState.complete* state after the [onRefresh] function completes.
122+
123+
This value is optional, specifying it will enable the optional *IndicatorState.complete* state.
98124

99-
The best way to understand how the _CustomRefreshIndicator_ widget changes its controller data is to see the example 😉. An example is available in the example application.
125+
### notificationPredicate (ScrollNotificationPredicate)
126+
Determines whether the received [ScrollNotification] should be handled by this widget.
127+
128+
By default, it only accepts *0* depth level notifications. This can be helpful for more complex layouts with nested scrollviews.
100129

101-
[![Controller data example](readme/controller_data.gif)](https://custom-refresh-indicator.klyta.it/#/presentation)
130+
### leadingScrollIndicatorVisible (bool)
131+
Whether to display leading scroll indicator (glow or stretch effect).
132+
### trailingScrollIndicatorVisible (bool)
133+
Whether to display trailing scroll indicator (glow or stretch effect).
134+
135+
### offsetToArmed (double?)
136+
The distance in number of pixels that the user should drag to arm the indicator. The armed indicator will trigger the *onRefresh* function when the gesture is completed.
137+
138+
If not specified, *containerExtentPercentageToArmed* argument will be used instead.
139+
140+
### containerExtentPercentageToArmed (double)
141+
The distance the user must scroll for the indicator to be armed, as a percentage of the scrollable's container extent.
142+
143+
If the *offsetToArmed* argument is specified, it will be used instead, and this value will not take effect.
144+
145+
The default value equals `0.1(6)`.
146+
147+
### trigger (IndicatorTrigger)
148+
Defines the trigger for the pull to refresh gesture.
149+
| value | Description |
150+
| ------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
151+
| **startEdge** | Pull to refresh can be triggered only from the **start** edge of the list. Mostly top side, but can be bottom for reversed ListView (with *reverse* argument set to true). |
152+
| **endEdge** | Pull to refresh can be triggered only from the **end** edge of the list. Mostly bottom, but can be top for reversed ListView (with *reverse* argument set to true). |
153+
| **bothEdges** | Pull to refresh can be triggered from **both edges** of the list. |
154+
155+
### triggerMode (IndicatorTriggerMode)
156+
Configures how *CustomRefreshIndicator* widget can be triggered. Works in the same way as the triggerMode of the built-in *RefreshIndicator* widget.
102157

103-
[Online example](https://custom-refresh-indicator.klyta.it/#/presentation)
158+
Defaults to *IndicatorTriggerMode.onEdge*.
104159

105-
| state | value | value description | Description |
106-
| ------------ | :------ | :------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
107-
| **idle** | `==0.0` | Value eqals `0.0`. | No user action. |
108-
| **dragging** | `=<0.0` | Value is eqal `0.0` or larger but lower than `1.0`. | User is dragging the indicator. |
109-
| **armed** | `>=1.0` | Value is larger than `1.0`. | User dragged the indicator further than the distance declared by `extentPercentageToArmed` or `offsetToArmed`. User still keeps the finger on the screen. |
110-
| **loading** | `>=1.0` | Value decreses from last `armed` state value in duration of `armedToLoadingDuration` argument to `1.0`. | User finished dragging (took his finger off the screen), when state was equal to `armed`. `onRefresh` function is called. |
111-
| **hiding** | `<=1.0` | Value decreses in duration of `draggingToIdleDuration` or `loadingToIdleDuration` arguments to `0.0`. | Indicator is hiding after:<br />- User ended dragging when indicator was in `dragging` state.<br />- Future returned from `onRefresh` function is resolved.<br />- Complete state ended.<br />- User started scrolling through the list. |
112-
| **complete** | `==1.0` | Value equals `1.0` for duration of `completeStateDuration` argument. | **This state is OPTIONAL, provide `completeStateDuration` argument with non null value to enable it.**<br /> Loading is completed. |
160+
| value | Description |
161+
| ------------ | :--------------------------------------------------------------------------------------------------------- |
162+
| **anywhere** | The indicator can be triggered regardless of the scroll position of the *Scrollable* when the drag starts. |
163+
| **onEdge** | The indicator can only be triggered if the *Scrollable* is at the edge when the drag starts. |
164+
165+
### autoRebuild (bool)
166+
When set to *true*, the *builder* function will be triggered whenever the controller changes. This can be useful for optimizing performance in complex widgets. When setting this to *false*, you can manage which part of the ui you want to rebuild, such as using the *AnimationBuilder* widget in conjunction with *IndicatorController*.
167+
168+
The default is *true*.
169+
170+
## IndicatorController
171+
172+
The best way to understand how the _CustomRefreshIndicator_ widget changes the data of its controller is to look at the example 😉.
173+
Open the sample application and try it yourself ([online example](https://custom-refresh-indicator.klyta.it/#/presentation)).
174+
175+
[![Controller data example](readme/controller_data.gif)](https://custom-refresh-indicator.klyta.it/#/presentation)
176+
177+
### state
178+
The following table describes each state of the indicator controller.
179+
180+
| value | Description |
181+
| -------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
182+
| **idle** | In this state, the indicator is not visible. No user action is performed. Value remains at *0.0*. |
183+
| **dragging** | The user starts scrolling/dragging the pointer to refresh. Releasing the pointer in this state will not trigger the *onRefresh* function. The controller value changes from *0.0* to *1.0*. |
184+
| **canceling** | The function *onRefresh* **has not been executed**, and the indicator is hidding from its current value that is lower than *1.0* to *0.0*. |
185+
| **armed** | The user has dragged the pointer further than the distance declared by *containerExtentPercentageToArmed* or *offsetToArmed* (over the value of *1.0*). Releasing the pointer in this state will trigger the *onRefresh* function. |
186+
| **loading** | The user has released the indicator in the armed state. The indicator settles on its target value *1.0* and the *onRefresh* function is called. |
187+
| **complete** | **OPTIONAL** - Provide `completeStateDuration` argument to enable it. The *onRefresh* callback has completed and the pointer remains at value *1.0* for the specified duration. |
188+
| **finalizing** | The *onRefresh* function **has been executed**, and the indicator hides from the value *1.0* to *0.0*. |
113189

114190
---
115191

192+
### edge (IndicatorEdge?)
193+
Whether the pull to refresh gesture is triggered from the start of the list or from the end.
194+
195+
This is especially useful with the *trigger* argument set to `IndicatorTrigger.bothEdges`, as the gesture can then be triggered from start and end edge.
196+
197+
It is null when the edge is still not determined by the *CustomRefreshIndicator* widget.
198+
| value | Description |
199+
| --------- | :-------------------------------------------------------- |
200+
| **start** | The indicator was started from the beginning of the list. |
201+
| **end** | The indicator was started from the end of the list. |
202+
203+
### side (IndicatorSide)
204+
The side of the scrollable on which the indicator should be displayed.
205+
| value | Description |
206+
| ---------- | :--------------------------------------------------------------------- |
207+
| **top** | The indicator should be displayed on the **top** of the scrollable. |
208+
| **bottom** | The indicator should be displayed on the **bottom** of the scrollable. |
209+
| **left** | The indicator should be displayed on the **left** of the scrollable. |
210+
| **right** | The indicator should be displayed on the **right** of the scrollable. |
211+
| **none** | The indicator should not be displayed. |
212+
### direction (AxisDirection)
213+
The direction in which the list scrolls.
214+
215+
### scrollingDirection (ScrollDirection)
216+
The direction in which the user scrolls.
217+
218+
___
219+
116220
### Support
117221

118222
If you like this package, you have learned something from it, or you just don't know what to do with your money 😅 just buy me a cup of coffee ☕️ and this dose of caffeine will put a smile on my face which in turn will help me improve this package. Also as a thank you, you will be mentioned in this readme as a sponsor.

example/lib/screens/presentation_screen.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@ class _PresentationScreenState extends State<PresentationScreen> {
4343
AnimatedBuilder(
4444
animation: _controller,
4545
builder: (BuildContext context, Widget? child) {
46-
return AnimatedAlign(
47-
curve: Curves.easeInOut,
48-
duration: const Duration(seconds: 1),
46+
return Align(
4947
alignment: _controller.side.isNone
5048
? Alignment.center
5149
: _controller.side.isBottom

lib/src/controller.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class IndicatorController extends ChangeNotifier {
3939
_scrollingDirection = userScrollDirection;
4040
}
4141

42-
/// Direction in which user is scrolling
42+
/// The direction in which the user scrolls.
4343
ScrollDirection get scrollingDirection => _scrollingDirection;
4444

4545
/// Scrolling is happening in the positive scroll offset direction.
@@ -81,6 +81,7 @@ class IndicatorController extends ChangeNotifier {
8181
_edge = edge;
8282
}
8383

84+
/// The side of the scrollable on which the indicator should be displayed.
8485
IndicatorSide get side {
8586
final edge = this.edge;
8687
if (edge == null) return IndicatorSide.none;
@@ -96,7 +97,7 @@ class IndicatorController extends ChangeNotifier {
9697
}
9798
}
9899

99-
/// The direction in which list scrolls
100+
/// The direction in which the list scrolls
100101
///
101102
/// For example:
102103
/// ```

0 commit comments

Comments
 (0)