Skip to content

Commit 69456ab

Browse files
docs: standardize README with pt-BR translation and update outdated
content - Aligns the README format with other projects using a language switcher and author section. - Documents features missing since `0.5.1`, including controller, pull-to-refresh, `onError`/`onItemsLoaded`, and `ListView` passthrough. - Removes the outdated pub/popularity badge because pub.dev no longer exposes `popularityScore`.
1 parent 3312f67 commit 69456ab

2 files changed

Lines changed: 590 additions & 33 deletions

File tree

README.md

Lines changed: 141 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
</div>
66
<br>
77

8+
<p align="center">
9+
<strong>Language:</strong>
10+
<strong>English</strong> | <a href="README.pt.md">Português</a>
11+
</p>
12+
813
<h1 align="center">Scroll Infinity</h1>
914

1015
<p align="center">
@@ -23,7 +28,6 @@
2328
<img src="https://img.shields.io/pub/v/scroll_infinity.svg">
2429
<img src="https://img.shields.io/pub/likes/scroll_infinity">
2530
<img src="https://img.shields.io/pub/points/scroll_infinity">
26-
<img src="https://img.shields.io/pub/popularity/scroll_infinity">
2731
</div>
2832

2933
## Table of Contents
@@ -32,10 +36,16 @@
3236
- [Features](#features)
3337
- [Built With](#built-with)
3438
- [Getting Started](#getting-started)
39+
- [Requirements](#requirements)
40+
- [Installation](#installation)
3541
- [Usage](#usage)
3642
- [Basic Vertical Scroll](#basic-vertical-scroll)
3743
- [Basic Horizontal Scroll](#basic-horizontal-scroll)
3844
- [Vertical Scroll with Interval](#vertical-scroll-with-interval)
45+
- [Controller (Refresh & Retry)](#controller-refresh--retry)
46+
- [Pull-to-Refresh](#pull-to-refresh)
47+
- [Manual Loading](#manual-loading)
48+
- [Error and Analytics Callbacks](#error-and-analytics-callbacks)
3949
- [Properties](#properties)
4050
- [Contributing](#contributing)
4151
- [License](#license)
@@ -67,15 +77,29 @@ It offers customization for manual/automatic loading, custom state widgets, and
6777
- Insert null values at intervals (ads/dividers)
6878
- Retry attempts limit on error
6979
- Real item index mapping with intervals
80+
- `ScrollInfinityController` for external refresh/retry
81+
- Pull-to-refresh support
82+
- Configurable load-more trigger threshold
83+
- `onError` and `onItemsLoaded` callbacks for logging/analytics
84+
- Passthrough of `physics`, `shrinkWrap`, `primary`, and `cacheExtent` to the underlying `ListView`
7085

7186
## Built With
7287

73-
- **[Flutter](https://flutter.dev/)** A UI toolkit by Google for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase.
74-
- **[Dart](https://dart.dev/)** The programming language used for Flutter, optimized for building fast apps on any platform.
88+
- **[Flutter](https://flutter.dev/)** - A UI toolkit by Google for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase.
89+
- **[Dart](https://dart.dev/)** - The programming language used for Flutter, optimized for building fast apps on any platform.
7590

7691
## Getting Started
7792

78-
Install:
93+
### Requirements
94+
95+
| Requirement | Version |
96+
| ----------- | ---------- |
97+
| Dart SDK | >=3.3.4 |
98+
| Flutter SDK | >=1.17.0 |
99+
100+
Supports Android, iOS, web, Windows, Linux, and macOS.
101+
102+
### Installation
79103

80104
```bash
81105
flutter pub add scroll_infinity
@@ -88,6 +112,8 @@ If `loadData` returns `null`, the error state is shown.
88112

89113
**Note:** Use a nullable type `T?` when using `interval`, as null values are inserted.
90114

115+
A fully configurable demo with every property wired to UI controls is available in the [example](example) directory.
116+
91117
### Basic Vertical Scroll
92118

93119
```dart
@@ -255,43 +281,125 @@ class _MyAppState extends State<MyApp> {
255281
}
256282
```
257283

284+
### Controller (Refresh & Retry)
285+
286+
Use a `ScrollInfinityController` to trigger `refresh()`/`retry()` from outside the widget (e.g. a button) and to read `isLoading`/`hasError`. Dispose it in `dispose()` since you created it.
287+
288+
```dart
289+
final _controller = ScrollInfinityController();
290+
291+
@override
292+
void dispose() {
293+
_controller.dispose();
294+
super.dispose();
295+
}
296+
297+
@override
298+
Widget build(BuildContext context) {
299+
return ScrollInfinity<int>(
300+
controller: _controller,
301+
maxItems: _maxItems,
302+
loadData: _loadData,
303+
itemBuilder: _itemBuilder,
304+
);
305+
}
306+
307+
// Elsewhere, e.g. a FloatingActionButton:
308+
onPressed: () => _controller.refresh(),
309+
```
310+
311+
### Pull-to-Refresh
312+
313+
Set `enablePullToRefresh` to wrap the list in a `RefreshIndicator` that resets pagination back to `initialPageIndex`.
314+
315+
```dart
316+
ScrollInfinity<int>(
317+
enablePullToRefresh: true,
318+
maxItems: _maxItems,
319+
loadData: _loadData,
320+
itemBuilder: _itemBuilder,
321+
)
322+
```
323+
324+
### Manual Loading
325+
326+
Set `automaticLoading` to `false` to show a "Load More" button instead of fetching automatically on scroll. Customize it with `loadMoreBuilder`.
327+
328+
```dart
329+
ScrollInfinity<int>(
330+
automaticLoading: false,
331+
loadMoreBuilder: (action) {
332+
return TextButton(
333+
onPressed: action,
334+
child: const Text('Load more'),
335+
);
336+
},
337+
maxItems: _maxItems,
338+
loadData: _loadData,
339+
itemBuilder: _itemBuilder,
340+
)
341+
```
342+
343+
### Error and Analytics Callbacks
344+
345+
Use `onError` to log/report the raw exception thrown by `loadData`, and `onItemsLoaded` to observe successfully fetched items (e.g. analytics). Neither affects the build.
346+
347+
```dart
348+
ScrollInfinity<int>(
349+
onError: (error) => log('Failed to load items', error: error),
350+
onItemsLoaded: (items) => analytics.logEvent('items_loaded', {'count': items.length}),
351+
maxItems: _maxItems,
352+
loadData: _loadData,
353+
itemBuilder: _itemBuilder,
354+
)
355+
```
356+
258357
## Properties
259358

260359
**Core Data Handling**
261360

262-
| Name | Type | Default | Description |
263-
| ---------------- | ------------------------------------- | ------- | ------------------------ |
264-
| loadData | `Future<List<T>?> Function(int)` || Fetch data for each page |
265-
| itemBuilder | `Widget Function(T value, int index)` || Builds each item |
266-
| maxItems | `int` || Max items per request |
267-
| initialItems | `List<T>?` | null | Items before first fetch |
268-
| initialPageIndex | `int` | 0 | Starting page index |
361+
| Name | Type | Default | Description |
362+
| ---------------- | ------------------------------------- | ------- | ------------------------------------------------ |
363+
| loadData | `Future<List<T>?> Function(int)` | - | Fetch data for each page |
364+
| itemBuilder | `Widget Function(T value, int index)` | - | Builds each item |
365+
| maxItems | `int` | - | Max items per request |
366+
| initialItems | `List<T>?` | null | Items before first fetch |
367+
| initialPageIndex | `int` | 0 | Starting page index |
368+
| controller | `ScrollInfinityController?` | null | External refresh/retry and loading/error state |
369+
| onItemsLoaded | `void Function(List<T> items)?` | null | Called with fetched items on each successful load |
269370

270371
**Layout & Appearance**
271372

272-
| Name | Type | Default | Description |
273-
| ---------------- | ------------------------------------- | -------- | -------------------------------------------------- |
274-
| scrollDirection | `Axis` | vertical | Scroll direction |
275-
| reverse | `bool` | false | Reverses scroll/growth direction (e.g. chat lists) |
276-
| padding | `EdgeInsetsGeometry?` | null | Internal padding |
277-
| header | `Widget?` | null | Header widget |
278-
| separatorBuilder | `Widget Function(BuildContext, int)?` | null | Separators |
279-
| scrollbars | `bool` | true | Show scrollbars |
373+
| Name | Type | Default | Description |
374+
| ------------------- | ------------------------------------- | -------- | -------------------------------------------------- |
375+
| scrollDirection | `Axis` | vertical | Scroll direction |
376+
| reverse | `bool` | false | Reverses scroll/growth direction (e.g. chat lists) |
377+
| padding | `EdgeInsetsGeometry?` | null | Internal padding |
378+
| header | `Widget?` | null | Header widget |
379+
| separatorBuilder | `Widget Function(BuildContext, int)?` | null | Separators |
380+
| scrollbars | `bool` | true | Show scrollbars |
381+
| enablePullToRefresh | `bool` | false | Wraps list in a `RefreshIndicator` |
382+
| physics | `ScrollPhysics?` | null | Passed to the underlying `ListView` |
383+
| shrinkWrap | `bool` | false | Passed to the underlying `ListView` |
384+
| primary | `bool?` | null | Passed to the underlying `ListView` |
385+
| cacheExtent | `double?` | null | Passed to the underlying `ListView` |
280386

281387
**Behavioral Features**
282388

283-
| Name | Type | Default | Description |
284-
| ---------------- | ------ | ------- | ---------------------------- |
285-
| interval | `int?` | null | Null item insertion interval |
286-
| useRealItemIndex | `bool` | true | Independent indexing |
287-
| automaticLoading | `bool` | true | Auto-fetch on scroll |
389+
| Name | Type | Default | Description |
390+
| ----------------- | -------- | ------- | ------------------------------------------------ |
391+
| interval | `int?` | null | Null item insertion interval |
392+
| useRealItemIndex | `bool` | true | Independent indexing |
393+
| automaticLoading | `bool` | true | Auto-fetch on scroll |
394+
| loadMoreThreshold | `double` | 200 | Distance from list end that triggers the next page |
288395

289396
**Error Handling**
290397

291-
| Name | Type | Default | Description |
292-
| ------------------ | ------ | ------- | ----------- |
293-
| enableRetryOnError | `bool` | true | Allow retry |
294-
| maxRetries | `int?` | null | Retry limit |
398+
| Name | Type | Default | Description |
399+
| ------------------ | ----------------------------- | ------- | ----------------------------------- |
400+
| enableRetryOnError | `bool` | true | Allow retry |
401+
| maxRetries | `int?` | null | Retry limit |
402+
| onError | `void Function(Object error)?` | null | Called with the exception on failure |
295403

296404
**State-Specific Widgets**
297405

@@ -334,8 +442,8 @@ Distributed under the MIT License. See the [LICENSE](LICENSE) file for more info
334442

335443
Developed by **Dário Matias**:
336444

337-
- **Portfolio**: [dariomatias-dev](https://dariomatias-dev.com)
338-
- **GitHub**: [dariomatias-dev](https://github.com/dariomatias-dev)
339-
- **Email**: [matiasdario75@gmail.com](mailto:matiasdario75@gmail.com)
340-
- **Instagram**: [@dariomatias_dev](https://instagram.com/dariomatias_dev)
341-
- **LinkedIn**: [linkedin.com/in/dariomatias-dev](https://linkedin.com/in/dariomatias-dev)
445+
- Portfolio: [https://dariomatias-dev.com](https://dariomatias-dev.com)
446+
- GitHub: [https://github.com/dariomatias-dev](https://github.com/dariomatias-dev)
447+
- Email: [matiasdario75@gmail.com](mailto:matiasdario75@gmail.com)
448+
- Instagram: [https://instagram.com/dariomatias_dev](https://instagram.com/dariomatias_dev)
449+
- LinkedIn: [https://linkedin.com/in/dariomatias-dev](https://linkedin.com/in/dariomatias-dev)

0 commit comments

Comments
 (0)