π§© Flutter Chat Pagination
A lightweight and efficient chat pagination system for Flutter β built with Riverpod and FlutterListView for seamless infinite scrolling, smooth state handling, and full UI flexibility.
π Features
- β‘ Infinite scrolling β load messages in pages (up or down)
- π¬ Customizable message builder β you control the UI
- π§ Riverpod-powered state management β reactive and clean
- π Smart preload thresholds β efficient, automatic page requests
- π¨ Composable design β works with any message bubble layout
- π¦ Simple controller API β easy to integrate and extend
π Getting Started
1. Install the package
Add the dependency in your pubspec.yaml:
dependencies:
flutter_chat_pagination:
git:
url: https://github.com/YimaPhilemon/chat_pagination.git
Or
dependencies:
flutter_chat_pagination: ^0.0.2
Then run:
flutter pub get
π§± Architecture Overview This package is built around three core layers:
Component Type Responsibility ChatPaginationView Widget Displays the chat list and handles scroll detection ChatPaginationController Class Controls pagination requests, scrolling, and triggers ChatPaginationNotifier StateNotifier Manages message state, loading, and pagination flags
π‘ Basic Usage
- Import dependencies
import 'package:flutter_chat_paginator/flutter_chat_paginator.dart';
- Initialize in your main app
void main() {
runApp(const ProviderScope(child: ChatApp()));
}
- Create the Chat Screen
class ChatApp extends ConsumerStatefulWidget {
const ChatApp({super.key});
@override
ConsumerState<ChatApp> createState() => _ChatAppState();
}
class _ChatAppState extends ConsumerState<ChatApp> {
late final ChatPaginationController controller;
@override
void initState() {
super.initState();
controller = ChatPaginationController(
ref: ref,
onPageRequestCallback: (pageIndex, pageSize) async {
// Simulate API call
await Future.delayed(const Duration(seconds: 1));
final messages = List.generate(
pageSize,
(i) => "Message ${(pageIndex * pageSize) + i + 1}",
);
controller.addMessages(messages, prepend: true);
},
);
controller.loadFirstPage();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Chat Pagination Example')),
body: ChatPaginationView(
controller: controller,
itemBuilder: (context, index, message) {
return Container(
padding: const EdgeInsets.all(8),
margin: const EdgeInsets.symmetric(vertical: 4),
decoration: BoxDecoration(
color: Colors.orange.shade50,
borderRadius: BorderRadius.circular(12),
),
child: Text(message),
);
},
),
),
);
}
}
βοΈ Configuration Options You can tweak scrolling behavior and thresholds easily:
Parameter Default Description pageMinTriggerOffset 200.0 Minimum scroll offset to trigger next page pageMaxTriggerOffset 800.0 Maximum threshold to cap trigger distance disableCacheItems true Disable item caching for dynamic lists keepPosition true Maintain scroll position after updates firstItemAlign FirstItemAlign.start Initial alignment of the list padding EdgeInsets.all(16) List padding
π Controller API Reference Method Description loadFirstPage() Loads the first page after initialization requestNextPage() Manually load the next page addMessages(List messages, {bool prepend = false}) Add a list of messages addMessage(dynamic message, {bool prepend = false}) Add a single message reset() Clears all messages and resets pagination scrollToBottom({bool animated = true}) Scrolls to the newest message
π§ State Notifier Reference ChatPaginationNotifier extends StateNotifier
Property Type Description messages List
π§© Example UI with FlutterListView The package uses FlutterListView under the hood to handle efficient scrolling with thousands of messages. You can safely append or prepend messages without losing scroll position.
FlutterListView(
controller: controller.listController,
delegate: FlutterListViewDelegate(
(context, index) {
final message = state.messages[index];
return ChatBubble(message: message);
},
childCount: state.messages.length,
),
);
π§° Advanced Example: Preloading Logic You can enable preload offset to stop pagination after a specific page count:
controller = ChatPaginationController(
ref: ref,
preloadOffset: 3, // after 3 pages, stop auto-loading
onPageRequestCallback: (pageIndex, pageSize) async {
...
},
);
π§Ό Resetting the Chat
controller.reset(); // Clears messages and resets the current page
π¦ Folder Structure
lib/
βββ chat_pagination_controller.dart
βββ chat_pagination_notifier.dart
βββ chat_pagination_view.dart
π¬ Future Plans β Bidirectional pagination (load older & newer messages)
β Auto-scroll during live message streaming
π Scroll anchor restoration across sessions
π Integration with popular chat APIs (Firebase, Supabase, etc.)
π Built-in message group headers (date separators)
π§βπ» Contributing Pull requests are welcome! If you find a bug or want to suggest an improvement, open an issue.
πͺͺ License This project is licensed under the MIT License. See the LICENSE file for details.
β€οΈ Credits Developed with π for the Flutter community.
