Flutter聊天列表展示插件lorien_chat_list的使用
Flutter聊天列表展示插件lorien_chat_list的使用
lorien_chat_list
是一个用于构建类似Messenger或WhatsApp聊天页面的包。与其他包的主要区别在于滚动部分——当有新消息时会自动滚动到底部,或者如果用户已经向上滚动了一定距离,则保持当前滚动位置(您可以设置该阈值)。
开始使用
在 pubspec.yaml
文件中添加依赖:
dependencies:
...
lorien_chat_list: ^0.0.1
基本用法
导入
import 'package:lorien_chat_list/lorien_chat_list.dart';
控制器
final ChatListController<int> _controller = ChatListController(
initialItems: List.generate(10, (index) => index),
);
添加项目到列表底部:
_controller.addToBottom(100);
添加一系列项目到列表底部:
_controller.addRangeToBottom([100, 200]);
添加项目到列表顶部:
_controller.addToTop(-100);
添加一系列项目到列表顶部:
_controller.addRangeToTop([-100, -200]);
清除所有项目并重置控制器到初始状态:
_controller.clearAll();
小部件
ChatList(
controller: _controller,
itemBuilder: (item, properties) => Text(
'${item.toString()} - ${properties.toString()}',
),
),
自定义(可选)
ChatList
loadingMoreWidget
- 在加载更多旧消息时(onLoadMoreCallback
)可见的顶部小部件onLoadMoreCallback
- 加载更多旧消息的函数。当达到列表顶部边缘时触发。应返回布尔值,true
表示还有更多的旧消息可以加载,否则false
表示已加载完毕。scrollController
- 滚动控制器scrollPhysics
- 滚动物理特性padding
- 列表填充spacing
- 项目之间的垂直间距useJumpTo
- 是否使用jumpTo
而不是animateTo
进行自动滚动animateToDuration
-animateTo
的持续时间,默认为 300 毫秒fadeInDuration
- 淡入持续时间,默认为 300 毫秒animateToCurve
-animateTo
的曲线,默认为Curves.easeInOut
fadeInCurve
- 淡入曲线,默认为Curves.easeInOut
bottomEdgeThreshold
- 自动滚动到底部项目的阈值,默认为 0
示例代码
以下是一个完整的示例代码,展示了如何使用 lorien_chat_list
包来创建一个聊天列表页面:
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:lorien_chat_list/lorien_chat_list.dart';
void main() {
runApp(const LorienChatListExample());
}
class LorienChatListExample extends StatefulWidget {
const LorienChatListExample({super.key});
[@override](/user/override)
State<LorienChatListExample> createState() => _LorienChatListExampleState();
}
class _LorienChatListExampleState extends State<LorienChatListExample> {
late final ChatListController<_MessageModel> _chatController = ChatListController(
initialItems: List.generate(10, (index) => -index)
.map(
(number) => _MessageModel(
number: number,
isMyMessage: _random.nextBool(),
text: _tolkienQuotes[number % _tolkienQuotes.length],
),
)
.toList(),
);
int _nextTopNumber = -10;
int _nextBottomNumber = 1;
final _random = Random();
final _scrollController = ScrollController();
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.black,
title: const Text(
'LORIEN.DEV Chat list',
style: TextStyle(
color: Colors.white,
),
),
actions: [
IconButton(
tooltip: 'Add item to top',
icon: const Icon(
Icons.add_comment_outlined,
color: Colors.white,
),
onPressed: () => _chatController.addToTop(
_MessageModel(
number: _nextTopNumber--,
isMyMessage: _random.nextBool(),
text: _tolkienQuotes[_nextTopNumber % _tolkienQuotes.length],
),
),
),
IconButton(
tooltip: 'Add item to bottom',
icon: const Icon(
Icons.add_comment,
color: Colors.white,
),
onPressed: () => _chatController.addToBottom(
_MessageModel(
number: _nextBottomNumber++,
isMyMessage: _random.nextBool(),
text: _tolkienQuotes[_nextBottomNumber % _tolkienQuotes.length],
),
),
),
IconButton(
tooltip: 'Clear list',
icon: const Icon(
Icons.refresh,
color: Colors.white,
),
onPressed: () {
_chatController.clearAll();
_nextTopNumber = 0;
_nextBottomNumber = 1;
},
),
],
),
body: ChatList(
controller: _chatController,
itemBuilder: (item, properties) => _MessageCard(
type: item.isMyMessage
? _MessageType.outgoing
: _MessageType.incoming,
text: '${item.number}. ${item.text}',
),
loadingMoreWidget: const Padding(
padding: EdgeInsets.only(top: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
],
),
),
onLoadMoreCallback: _loadMoreOldMessages,
scrollController: _scrollController,
scrollPhysics: const ClampingScrollPhysics(),
useJumpTo: false,
animateToDuration: const Duration(milliseconds: 300),
fadeInDuration: const Duration(milliseconds: 300),
animateToCurve: Curves.easeInOut,
fadeInCurve: Curves.easeInOut,
bottomEdgeThreshold: 20.0,
padding: const EdgeInsets.all(16.0),
spacing: 4.0,
),
),
);
}
/// 模拟加载更多旧消息。
/// 返回 *true* 如果还有更多的旧消息可以加载
/// 否则返回 *false* 如果已加载完毕。
Future<bool> _loadMoreOldMessages() async {
/// 模拟延迟3秒
await Future.delayed(const Duration(seconds: 3));
/// 获取10个更多的旧消息
final newOldItems = List.generate(10, (index) => _nextTopNumber--)
.map(
(number) => _MessageModel(
number: number,
isMyMessage: _random.nextBool(),
text: _tolkienQuotes[number % _tolkienQuotes.length],
),
)
.toList();
/// 将新的旧消息添加到聊天列表的顶部
_chatController.addRangeToTop(newOldItems);
/// 返回是否有更多的旧消息可以加载
return _nextTopNumber > -30;
}
}
class _MessageCard extends StatelessWidget {
const _MessageCard({
required _MessageType type,
required String text,
}) : _type = type,
_text = text;
final _MessageType _type;
final String _text;
[@override](/user/override)
Widget build(BuildContext context) {
final isIncoming = _type == _MessageType.incoming;
return Row(
mainAxisAlignment:
isIncoming ? MainAxisAlignment.start : MainAxisAlignment.end,
children: [
Flexible(
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * 0.7,
),
child: Card(
color: isIncoming ? Colors.white : Colors.black,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
_text,
style: TextStyle(
color: isIncoming ? Colors.black : Colors.white,
),
textAlign: isIncoming ? TextAlign.left : TextAlign.right,
),
),
),
),
),
],
);
}
}
class _MessageModel {
const _MessageModel({
required this.number,
required this.isMyMessage,
required this.text,
});
final int number;
final bool isMyMessage;
final String text;
}
enum _MessageType {
incoming,
outgoing,
}
const _tolkienQuotes = [
"\"All we have to decide is what to do with the time that is given us.\" "
"(The Fellowship of the Ring - J.R.R. Tolkien)",
"\"Not all those who wander are lost.\" (The Fellowship of the Ring - J.R.R. Tolkien)",
"\"Courage is found in unlikely places.\" (The Return of the King - J.R.R. Tolkien)",
"\"Even the smallest person can change the course of the future.\" (The Fellowship of the Ring - J.R.R. Tolkien)",
"\"It's a dangerous business, Frodo, going out your door. You step onto the road, "
"and if you don't keep your feet, "
"there's no knowing where you might be swept off to.\" (The Fellowship of the Ring - J.R.R. Tolkien)",
"\"I will not say: do not weep; for not all tears are an evil.\" (The Return of the King - J.R.R. Tolkien)",
"\"Far over the misty mountains cold, To dungeons deep and caverns old, We must away, ere break of day, To seek "
"the pale enchanted gold.\" (The Hobbit - J.R.R. Tolkien)",
"\"The world is indeed full of peril, and in it there are many dark places; but still there is much that is fair, "
"and though in all lands love is now mingled with grief, it grows perhaps the greater.\" "
"(The Fellowship of the Ring - J.R.R. Tolkien)",
"\"War must be, while we defend our lives against a destroyer who would devour all; but I do not love the bright"
" sword for its sharpness, nor the arrow for its swiftness, nor the warrior for his glory. I love only that"
" which they defend.\" (The Two Towers - J.R.R. Tolkien)",
"\"There are older and fouler things than Orcs in the deep places of the world.\" "
"(The Fellowship of the Ring - J.R.R. Tolkien)"
];
更多关于Flutter聊天列表展示插件lorien_chat_list的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter聊天列表展示插件lorien_chat_list的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
lorien_chat_list
是一个 Flutter 插件,用于展示聊天列表。它提供了丰富的功能,如消息气泡、头像、时间戳、未读消息计数等,可以帮助开发者快速构建一个功能完善的聊天界面。
安装插件
首先,你需要在 pubspec.yaml
文件中添加 lorien_chat_list
依赖:
dependencies:
flutter:
sdk: flutter
lorien_chat_list: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来安装插件。
基本使用
下面是一个简单的示例,展示了如何使用 lorien_chat_list
插件来展示聊天列表。
import 'package:flutter/material.dart';
import 'package:lorien_chat_list/lorien_chat_list.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ChatListScreen(),
);
}
}
class ChatListScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Chat List'),
),
body: LorienChatList(
items: [
ChatItem(
name: 'John Doe',
message: 'Hey, how are you?',
time: '10:30 AM',
avatar: 'https://via.placeholder.com/150',
unreadCount: 2,
),
ChatItem(
name: 'Jane Smith',
message: 'Can we meet tomorrow?',
time: 'Yesterday',
avatar: 'https://via.placeholder.com/150',
unreadCount: 0,
),
// Add more ChatItem objects here
],
onItemTap: (ChatItem item) {
print('Tapped on ${item.name}');
// Navigate to chat detail screen or perform other actions
},
),
);
}
}
参数说明
-
items
: 一个ChatItem
对象的列表,每个ChatItem
代表一个聊天项。name
: 聊天对象的名称。message
: 最后一条消息的内容。time
: 最后一条消息的时间。avatar
: 聊天对象的头像 URL。unreadCount
: 未读消息的数量。
-
onItemTap
: 当用户点击某个聊天项时触发的回调函数。
自定义样式
lorien_chat_list
提供了多种自定义选项,你可以通过传递不同的参数来调整聊天列表的外观。例如:
LorienChatList(
items: [
// ChatItem objects
],
backgroundColor: Colors.white,
itemBackgroundColor: Colors.grey[200],
avatarRadius: 25,
titleStyle: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
subtitleStyle: TextStyle(fontSize: 14, color: Colors.grey),
timeStyle: TextStyle(fontSize: 12, color: Colors.grey[600]),
unreadCountStyle: TextStyle(fontSize: 12, color: Colors.white),
unreadCountBackgroundColor: Colors.red,
onItemTap: (ChatItem item) {
// Handle item tap
},
);