chat_ui_kit
一個完整的 Flutter 聊天 UI 套件
- 星標
- 132
- 分支
- 39
- 最近推送(UTC)
- 2023年6月8日
- 專案狀態
- 未封存
原始 README
以下為英文專案原文快照,最新內容請造訪 GitHub。
A complete Flutter chat UI kit
This Flutter package provides you with a base structure as well as a set of tools that allow you to quickly build up a modern chat UI. Instead of trying to come up with all in one Widgets that meet everyone's expectations, you are given helpers that are meant to be used as examples and customized at will.

Features
- Support for group conversations
- List of conversations (chats)
- Group avatar
- Unread messages badge
- Message title (user)
- Message avatar
- Adaptive message containers depending on relative positioning
- Controllers with data management api (add, remove, update)
- Automated selection management
- Message input with typing events
- Examples for text, image, audio and video messages
Getting Started
First add the following line to your pubspec.yaml dependencies:
chat_ui_kit: ^[latest_version]
Next, setup your models to extend the base models:
class ChatMessage extends MessageBase {
//...
ChatUser author;
String text;
@override
DateTime get createdAt =>
DateTime.fromMillisecondsSinceEpoch(creationTimestamp);
@override
String get id => messageId;
@override
String get url => attachment;
@override
MessageBaseType get messageType {
//...
}
}
class ChatUser extends UserBase {
//...
@override
String get name => username;
@override
String get id => userid;
@override
String get avatar => avatarURL;
}
class Chat extends ChatBase {
//...
List<ChatUser> members;
ChatMessage lastMessage;
@override
int get unreadCount => chat.unreadCount;
@override
String get name {
if ((chat?.name ?? null).isNotNullOrEmpty()) return chat.name;
return membersWithoutSelf.map((e) => e.username).toList().join(", ");
}
@override
String get id => chat?.id;
@override
List<ChatUser> get membersWithoutSelf {
List<ChatUser> membersWithoutSelf = [];
final localUserId = chat?.localUserId ??
FirebaseAuth.instance.currentUser?.uid;
for (ChatUser chatUser in members) {
if (localUserId != chatUser.userid) membersWithoutSelf.add(chatUser);
}
return membersWithoutSelf;
}
}
ChatsListScreen
ChatsListController controller = ChatsListController();
ChatsList(
controller: _controller,
appUserId: _currentUser.id,
scrollHandler: _handleScrollEvent,
groupAvatarStyle: GroupAvatarStyle(withSeparator: true),
builders: ChatsListTileBuilders(
groupAvatarBuilder:
(context, imageIndex, itemIndex, size, item) {
final chat = item as Chat;
return CachedNetworkImage(
cacheManager: CustomCacheManager(),
imageUrl: chat.membersWithoutSelf[imageIndex].avatar,
width: size.width,
height: size.height,
fit: BoxFit.cover,
errorWidget: (ctx, url, val) =>
AppErrorWidget(true, size: size));
},
lastMessageBuilder: _buildLastMessage,
wrapper: _buildTileWrapper,
dateBuilder: (context, date) => Padding(
padding: EdgeInsets.only(left: 16),
child: Text(DateFormatter.getVerboseDateTimeRepresentation(
context, date)))))
@override
void dispose() {
_controller.dispose();
super.dispose();
}
ChatScreen
final MessagesListController _controller = MessagesListController();
@override
void initState() {
_controller.selectionEventStream.listen((event) {
setState(() {
_selectedItemsCount = event.currentSelectionCount;
});
});
super.initState();
}
Widget _buildMessagesList() {
IncomingMessageTileBuilders incomingBuilders = _isGroupChat
? IncomingMessageTileBuilders(
bodyBuilder: (context, index, item, messagePosition) =>
_buildMessageBody(context, index, item, messagePosition,
MessageFlow.incoming),
avatarBuilder: (context, index, item, messagePosition) {
final _chatMessage = item as ChatMessage;
return Padding(
padding:
EdgeInsets.only(right: 16),
child: _buildAvatarWithScore(_chatMessage.author));
})
: IncomingMessageTileBuilders(
bodyBuilder: (context, index, item, messagePosition) =>
_buildMessageBody(context, index, item, messagePosition,
MessageFlow.incoming),
titleBuilder: null);
return Expanded(
child: MessagesList(
controller: _controller,
appUserId: _currentUser.id,
useCustomTile: (i, item, pos) {
final msg = item as ChatMessage;
return msg.isTypeEvent;
},
messagePosition: _messagePosition,
builders: MessageTileBuilders(
customTileBuilder: _buildEventMessage,
customDateBuilder: _buildDate,
incomingMessageBuilders: incomingBuilders,
outgoingMessageBuilders: OutgoingMessageTileBuilders(
bodyBuilder: (context, index, item, messagePosition) =>
_buildMessageBody(context, index, item,
messagePosition, MessageFlow.outgoing)))));
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
More
Please make sure to browse the class inlined documentation before asking any questions. PRs are very welcome!
語言DartRubySwiftKotlinObjective-C
分類
使用的依賴
依賴清單 12 項
- flutter
{"sdk":"flutter"} - implicitly_animated_reorderable_list_2
^0.5.0 - intl
^0.18.0 - functional_widget_annotation
^0.10.0 - just_audio
^0.9.10 - flutter_video_info
^1.2.0 - video_thumbnail
^0.5.2 - collection
^1.15.0 - flutter_test開發依賴
{"sdk":"flutter"} - build_runner開發依賴
^2.0.3 - functional_widget開發依賴
^0.10.0 - mockito開發依賴
^5.0.15
如何選擇適合專案的儲存庫?
先依使用情境篩選,再比較專案活躍情況,最後到原始儲存庫確認使用要求。
- 透過儲存庫名稱、作者或描述搜尋,再依技術分類縮小範圍。
- 綜合星標、分支與最近推送比較專案;星標反映社群關注,不保證品質。
- 使用前在 GitHub 確認 README、授權條款與 Issues。
來源與維護
“A repository is the most basic element of GitHub.”
GitHub Docs — About repositories ↗