flex_infinity_view 0.1.0
flex_infinity_view: ^0.1.0 copied to clipboard
Flexible infinite scrolling for Flutter lists, grids, and staggered layouts with loading, empty, and error states.
example/example.md
Basic usage #
This file is intended for the Example tab on pub.dev.
Standalone widget #
Use FlexInfinityView when the package should manage its own scrollable.
import 'package:flex_infinity_view/flex_infinity_view.dart';
import 'package:flutter/material.dart';
class ProductList extends StatefulWidget {
const ProductList({super.key});
@override
State<ProductList> createState() => _ProductListState();
}
class _ProductListState extends State<ProductList> {
final List<String> _items = [];
bool _isLoading = false;
bool _hasError = false;
bool _hasMore = true;
Future<void> _loadMore(int page, int limit) async {
if (_isLoading) return;
setState(() {
_isLoading = true;
_hasError = false;
});
try {
await Future<void>.delayed(const Duration(milliseconds: 500));
final nextItems = List.generate(
limit,
(index) => 'Item ${(page - 1) * limit + index + 1}',
);
setState(() {
_items.addAll(nextItems);
_hasMore = page < 4;
});
} catch (_) {
setState(() => _hasError = true);
} finally {
setState(() => _isLoading = false);
}
}
@override
Widget build(BuildContext context) {
return FlexInfinityView<String>(
items: _items,
limit: 8,
isLoading: _isLoading,
hasError: _hasError,
hasMore: _hasMore,
onLoadMore: _loadMore,
itemBuilder: (context, item, index) {
return ListTile(title: Text(item));
},
);
}
}
loadingWidget is optional. If you omit it, the package uses a centered CircularProgressIndicator by default.
Sliver usage #
Use FlexInfinitySliverView when the package must live inside an existing CustomScrollView.
CustomScrollView(
slivers: [
const SliverAppBar(
pinned: true,
title: Text('Products'),
),
FlexInfinitySliverView<String>(
items: items,
limit: 12,
isLoading: isLoading,
hasError: hasError,
hasMore: hasMore,
layoutType: InfiniteLayoutType.grid,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.78,
),
onLoadMore: fetchProducts,
itemBuilder: (context, item, index) {
return Padding(
padding: const EdgeInsets.all(8),
child: Card(child: Center(child: Text(item))),
);
},
),
],
)
Key parameters #
items: accumulated list rendered by the widget.onLoadMore: callback called with(page, limit)when more data is needed.isLoading: prevents duplicate requests and controls the initial loading state.hasError: renderserrorWidgetduring the first request.hasMore: stops pagination when there are no more pages.loadingWidget: custom UI for the first load.layoutType:InfiniteLayoutType.list,grid, orstaggered.gridDelegate: required whenlayoutTypeisInfiniteLayoutType.grid.
Complete demo #
The full demo app lives in example/lib/main.dart and includes:
- standalone
FlexInfinityView FlexInfinitySliverViewinsideCustomScrollView- list, grid, and staggered layouts
- empty state
- initial error state
- next-page error handling