flutter_infinite_chat_list 0.1.1
flutter_infinite_chat_list: ^0.1.1 copied to clipboard
A high-performance, generic animated chat list widget for Flutter with bi-directional infinite pagination, scroll-to-index, animated mutations, and keyboard-aware spacing.
flutter_infinite_chat_list #
A high-performance, generic animated chat list widget for Flutter.
Features #
- Bi-directional infinite pagination — load older messages at the top, newer at the bottom
- Scroll position preservation — viewport stays stable when items are inserted at either end
- Scroll-to-index — jump to any item via
scrollview_observer - Animated mutations — insert, remove, update, and bulk-set with smooth animations
- Keyboard-aware spacing — smart bottom padding that accounts for composer height, safe area, and keyboard
- Scroll-to-bottom FAB — appears when scrolled away, with optional unread badge
- Fully generic — works with any item type
T, not tied to any SDK
Getting started #
dependencies:
flutter_infinite_chat_list: ^0.1.0
Usage #
// 1. Create a controller
final controller = ChatListController<Message>(
itemIdentity: (m) => m.id,
);
// 2. Load initial data
final messages = await fetchMessages();
controller.set(messages, animated: false);
controller.hasMoreOlder = true;
// 3. Build the widget
ChatListWidget<Message>(
controller: controller,
onLoadOlder: () => loadOlderMessages(),
onLoadNewer: () => loadNewerMessages(),
contentEquality: (a, b) => a.text == b.text,
itemBuilder: (context, message, index, animation) {
return SizeTransition(
sizeFactor: animation,
child: MessageBubble(message: message),
);
},
);
// 4. Mutate the list
controller.insert(newMessage, index: 0); // new message at bottom
controller.update(oldMsg, editedMsg); // edit in place
controller.remove(deletedMsg); // animated removal
controller.scrollToIndex(42); // jump to item
controller.scrollToBottom(); // scroll to newest
How pagination works #
The list is a reversed CustomScrollView. Index 0 is the newest item (bottom of screen), higher indices are older (top of screen).
- Older items —
onLoadOlderfires when the user scrolls near the top. Insert atcontroller.length(end of list = top of screen). No scroll correction needed. - Newer items —
onLoadNewerfires when the user scrolls near the bottom. Insert at index 0. The widget automatically preserves scroll position using a hide → rebuild → scroll-to-anchor → reveal technique.
Example #
See the example directory for a complete working app with:
- 1000 pre-generated messages with random-length text
- Initial load from the middle (ids 200–300)
- Bi-directional pagination in pages of 20
- Send messages, scroll-to-middle, scroll-to-bottom FAB
Architecture #
ChatListController<T> — owns the item list, emits ItemOperation<T> stream
↓ operationsStream
ChatListWidget<T> — consumes operations, drives SliverAnimatedList
├── SliverViewObserver — scroll-to-index support
├── SliverAnimatedList — animated insert/remove
├── SliverSpacing — keyboard-aware bottom padding
├── ScrollToBottomButton — FAB with unread badge
└── LoadMoreIndicator — pagination spinners