lazy_scroll_view 1.0.0
lazy_scroll_view: ^1.0.0 copied to clipboard
A Flutter package that provides lazy-loading functionality for ListView and GridView
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:lazy_scroll_view/lazy_scroll_view.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Lazy Scroll View Examples',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Lazy Scroll Examples'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
_buildExampleCard(
context,
'LazyListView',
'Simple list with lazy loading',
() => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const SimpleListViewExample(),
),
),
),
_buildExampleCard(
context,
'LazyListView.builder',
'Dynamic list with builder pattern',
() => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const ListViewBuilderExample(),
),
),
),
_buildExampleCard(
context,
'LazyListView.separated',
'List with custom separators',
() => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const ListViewSeparatedExample(),
),
),
),
_buildExampleCard(
context,
'LazyGridView',
'Simple grid with lazy loading',
() => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const SimpleGridViewExample(),
),
),
),
_buildExampleCard(
context,
'LazyGridView.builder',
'Dynamic grid with builder pattern',
() => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const GridViewBuilderExample(),
),
),
),
_buildExampleCard(
context,
'LazyGridView.count',
'Grid with fixed count of items per row',
() => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const GridViewCountExample(),
),
),
),
],
),
);
}
Widget _buildExampleCard(
BuildContext context,
String title,
String subtitle,
VoidCallback onTap,
) {
return Card(
margin: const EdgeInsets.only(bottom: 12),
child: ListTile(
title: Text(title),
subtitle: Text(subtitle),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: onTap,
),
);
}
}
class SimpleListViewExample extends StatefulWidget {
const SimpleListViewExample({super.key});
@override
State<SimpleListViewExample> createState() => _SimpleListViewExampleState();
}
class _SimpleListViewExampleState extends State<SimpleListViewExample> {
final List<Widget> _items = List.generate(
20,
(index) => ListTile(
leading: CircleAvatar(child: Text('${index + 1}')),
title: Text('Item ${index + 1}'),
subtitle: Text('This is item number ${index + 1}'),
),
);
bool _isFinished = false;
Future<void> _loadMore() async {
await Future.delayed(const Duration(seconds: 2));
if (_items.length >= 100) {
setState(() => _isFinished = true);
return;
}
setState(() {
final startIndex = _items.length;
_items.addAll(
List.generate(
20,
(index) => ListTile(
leading: CircleAvatar(child: Text('${startIndex + index + 1}')),
title: Text('Item ${startIndex + index + 1}'),
subtitle: Text('This is item number ${startIndex + index + 1}'),
),
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Simple LazyListView')),
body: LazyListView(
padding: const EdgeInsets.all(16),
onLoad: _loadMore,
isFinished: _isFinished,
children: _items,
),
);
}
}
class ListViewBuilderExample extends StatefulWidget {
const ListViewBuilderExample({super.key});
@override
State<ListViewBuilderExample> createState() => _ListViewBuilderExampleState();
}
class _ListViewBuilderExampleState extends State<ListViewBuilderExample> {
final List<String> _items = List.generate(20, (i) => 'Item ${i + 1}');
bool _isFinished = false;
Future<void> _loadMore() async {
await Future.delayed(const Duration(seconds: 2));
if (_items.length >= 100) {
setState(() => _isFinished = true);
return;
}
setState(() {
_items.addAll(
List.generate(
20,
(i) => 'Item ${_items.length + i + 1}',
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('LazyListView.builder')),
body: LazyListView.builder(
itemCount: _items.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(child: Text('${index + 1}')),
title: Text(_items[index]),
subtitle: Text('This is item number ${index + 1}'),
);
},
onLoad: _loadMore,
isFinished: _isFinished,
),
);
}
}
class ListViewSeparatedExample extends StatefulWidget {
const ListViewSeparatedExample({super.key});
@override
State<ListViewSeparatedExample> createState() =>
_ListViewSeparatedExampleState();
}
class _ListViewSeparatedExampleState extends State<ListViewSeparatedExample> {
final List<String> _items = List.generate(20, (i) => 'Item ${i + 1}');
bool _isFinished = false;
Future<void> _loadMore() async {
await Future.delayed(const Duration(seconds: 2));
if (_items.length >= 100) {
setState(() => _isFinished = true);
return;
}
setState(() {
_items.addAll(
List.generate(
20,
(i) => 'Item ${_items.length + i + 1}',
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('LazyListView.separated')),
body: LazyListView.separated(
itemCount: _items.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(child: Text('${index + 1}')),
title: Text(_items[index]),
subtitle: Text('This is item number ${index + 1}'),
);
},
separatorBuilder: (context, index) => const Divider(height: 1),
onLoad: _loadMore,
isFinished: _isFinished,
),
);
}
}
class SimpleGridViewExample extends StatefulWidget {
const SimpleGridViewExample({super.key});
@override
State<SimpleGridViewExample> createState() => _SimpleGridViewExampleState();
}
class _SimpleGridViewExampleState extends State<SimpleGridViewExample> {
final List<Widget> _items = List.generate(
20,
(index) => Card(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.photo, size: 48, color: Colors.grey[400]),
const SizedBox(height: 8),
Text('Item ${index + 1}'),
],
),
),
);
bool _isFinished = false;
Future<void> _loadMore() async {
await Future.delayed(const Duration(seconds: 2));
if (_items.length >= 100) {
setState(() => _isFinished = true);
return;
}
setState(() {
final startIndex = _items.length;
_items.addAll(
List.generate(
20,
(index) => Card(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.photo, size: 48, color: Colors.grey[400]),
const SizedBox(height: 8),
Text('Item ${startIndex + index + 1}'),
],
),
),
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Simple LazyGridView')),
body: LazyGridView(
padding: const EdgeInsets.all(8),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
childAspectRatio: 1,
),
onLoad: _loadMore,
isFinished: _isFinished,
children: _items,
),
);
}
}
class GridViewBuilderExample extends StatefulWidget {
const GridViewBuilderExample({super.key});
@override
State<GridViewBuilderExample> createState() => _GridViewBuilderExampleState();
}
class _GridViewBuilderExampleState extends State<GridViewBuilderExample> {
final List<String> _items = List.generate(20, (i) => 'Item ${i + 1}');
bool _isFinished = false;
Future<void> _loadMore() async {
await Future.delayed(const Duration(seconds: 2));
if (_items.length >= 100) {
setState(() => _isFinished = true);
return;
}
setState(() {
_items.addAll(
List.generate(
20,
(i) => 'Item ${_items.length + i + 1}',
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('LazyGridView.builder')),
body: LazyGridView.builder(
padding: const EdgeInsets.all(8),
itemCount: _items.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
childAspectRatio: 1,
),
itemBuilder: (context, index) {
return Card(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.photo, size: 48, color: Colors.grey[400]),
const SizedBox(height: 8),
Text(_items[index]),
],
),
);
},
onLoad: _loadMore,
isFinished: _isFinished,
loadingIndicator: const Padding(
padding: EdgeInsets.all(16.0),
child: LinearProgressIndicator(),
),
),
);
}
}
class GridViewCountExample extends StatefulWidget {
const GridViewCountExample({super.key});
@override
State<GridViewCountExample> createState() => _GridViewCountExampleState();
}
class _GridViewCountExampleState extends State<GridViewCountExample> {
final List<String> _items = List.generate(20, (i) => 'Item ${i + 1}');
bool _isFinished = false;
Future<void> _loadMore() async {
await Future.delayed(const Duration(seconds: 2));
if (_items.length >= 100) {
setState(() => _isFinished = true);
return;
}
setState(() {
_items.addAll(
List.generate(
20,
(i) => 'Item ${_items.length + i + 1}',
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('LazyGridView with Count')),
body: LazyGridView.builder(
padding: const EdgeInsets.all(8),
itemCount: _items.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
childAspectRatio: 1,
),
itemBuilder: (context, index) {
return Card(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.photo, size: 32, color: Colors.grey[400]),
const SizedBox(height: 4),
Text(
_items[index],
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 12),
),
],
),
);
},
onLoad: _loadMore,
isFinished: _isFinished,
),
);
}
}