-
Notifications
You must be signed in to change notification settings - Fork 3
自定义消息页面(MessagesView)
杜洁鹏 edited this page Jun 7, 2024
·
2 revisions
消息页面提供了两种方式构造,两种方式都提供了对消息页面的自定义参数。
const MessagesView({
required this.profile,
this.appBar,
this.enableAppBar = true,
this.title,
this.inputBar,
this.controller,
this.showMessageItemAvatar,
this.showMessageItemNickname,
this.onItemTap,
this.onItemLongPress,
this.longPressActions,
this.onItemLongPressHandler,
this.onDoubleTap,
this.onAvatarTap,
this.onAvatarLongPress,
this.onNicknameTap,
this.emojiWidget,
this.itemBuilder,
this.alertItemBuilder,
this.bubbleStyle = ChatUIKitMessageListViewBubbleStyle.arrow,
this.morePressActions,
this.onMoreActionsItemsHandler,
this.replyBarBuilder,
this.quoteBuilder,
this.onErrorBtnTapHandler,
this.bubbleBuilder,
this.bubbleContentBuilder,
this.forceLeft,
this.inputBarTextEditingController,
this.multiSelectBottomBar,
this.viewObserver,
this.attributes,
this.onReactionItemTap,
this.onReactionInfoTap,
this.reactionItemsBuilder,
this.onThreadItemTap,
this.threadItemBuilder,
this.appBarTrailingActionsBuilder,
super.key,
});
@override
// profile: 消息接收方的信息, 可以是 `ChatUIKitProfile.contact` 或者 `ChatUIKitProfile.group`
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.gr(id: chatter),
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
appBar: AppBar(title: const Text('test')),
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
enableAppBar: false,
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
title: 'Chat',
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.group(id: groupId),
// defaultList: 默认的菜单项。
appBarTrailingActionsBuilder: (context, defaultList) {
return defaultList;
},
);
}
MessageListViewController
是 uikit 内部用来获取和操作数据用的控制器。
@override
Widget build(BuildContext context) {
final profile = ChatUIKitProfile.contact(id: chatter);
// 需要注意,构造 `MessageListViewController` 的 `profile` 要与构造 `MessagesView` 的一致。
final MessageListViewController controller = MessageListViewController(profile: profile);
return MessagesView(
profile: profile,
controller: controller,
);
}
}
如果自定义输入框,需要将输入框内的文字通过 MessageListViewController
发送。
final TextEditingController textController = TextEditingController();
@override
Widget build(BuildContext context) {
final profile = ChatUIKitProfile.contact(id: chatter);
// 需要注意,构造 `MessageListViewController` 的 `profile` 要与构造 `MessagesView` 的一致。
final MessageListViewController controller = MessageListViewController(profile: profile);
return MessagesView(
profile: profile,
controller: controller,
inputBar: Row(
children: [
Expanded(
child: TextField(
controller: textController,
),
),
InkWell(
onTap: () {
controller.sendTextMessage(textController.text);
textController.clear();
},
child: const SizedBox(
width: 40,
child: Text('Send'),
),
)
],
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
showMessageItemAvatar: (model) {
return false;
},
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
showMessageItemNickname: (model) {
return false;
},
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
// 如果你需要拦截点击事件返回 `true`, 如果你不处理,返回 `false`
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
onItemTap: (context, model) {
return false;
},
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
// 长按弹出菜单,返回 [] 则不弹出菜单
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息。
// defaultActions 默认的菜单项,包括了复制,删除等操作
onItemLongPressHandler: (context, model, defaultActions) {
return defaultActions;
},
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
// 如果你需要拦截点击事件返回 `true`, 如果你不处理,返回 `false`
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
onDoubleTap: (context, model) {
return false;
},
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
// 如果你需要拦截点击事件返回 `true`, 如果你不处理,返回 `false`
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
onAvatarTap: (context, model) {
return false;
},
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
// 如果你需要拦截点击事件返回 `true`, 如果你不处理,返回 `false`
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
onNicknameTap: (context, model) {
return false;
},
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
emojiWidget: Container(
height: 200,
color: Colors.red,
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
itemBuilder: (context, model) {
return ListTile(
title: Text(model.message.textContent),
);
},
);
}
提示消息主要是指 撤回消息,或者是加群之类的消息。
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
alertItemBuilder: (context, model) {
return const Text('XXX撤回了一条消息');
},
);
}
UIKit 提供了两种气泡样式,默认是 ChatUIKitMessageListViewBubbleStyle.arrow
。
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
bubbleStyle: ChatUIKitMessageListViewBubbleStyle.noArrow,
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
morePressActions: [
ChatUIKitBottomSheetItem.normal(label: 'take photo'),
],
);
}
也可以对 “更多” 按钮就行动态配置,当菜单弹出前才进行构建。
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
// defaultActions 默认要弹出的菜单,可以返回自己定义的菜单
onMoreActionsItemsHandler: (context, defaultActions) {
return defaultActions;
},
);
}
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
quoteBuilder: (context, model) {
return const Text('model.message');
},
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
// child: 消息内容 widget
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
bubbleBuilder: (context, child, model) {
return Container(
color: Colors.red,
padding: const EdgeInsets.all(8),
child: child,
);
},
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
bubbleContentBuilder: (context, model) {
return const Text('自定义内容');
},
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
forceLeft: true,
);
}
@override
Widget build(BuildContext context) {
// 多选后需要通过 `MessageListViewController` 得到选择的信息,所以需要构建一个 `MessageListViewController` 对象。
// 构建 `MessageListViewController` 时需要确保和构建 `MessagesView` 使用是使用的是一个 `profile` 。
final profile = ChatUIKitProfile.contact(id: chatter);
final MessageListViewController controller = MessageListViewController(profile: profile);
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
controller: controller,
multiSelectBottomBar: Row(
children: [
Expanded(
child: TextButton.icon(
onPressed: () {
if (controller.selectedMessages.isNotEmpty) {
// 跳转到 转发选择联系人页面
ChatUIKitRoute.pushOrPushNamed(
context,
ChatUIKitRouteNames.forwardMessageSelectView,
ForwardMessageSelectViewArguments(
messages: controller.selectedMessages,
isMulti: true,
),
).then((value) {
if (value == true) {
// 返回后需要关闭多选状态
controller.disableMultiSelectMode();
}
});
}
},
icon: const Icon(Icons.forward_10),
label: const Text('转发'),
),
)
],
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
// 只有群组支持 reaction
profile: ChatUIKitProfile.group(id: groupId),
// 点击后,默认弹出当前消息所有 `reaction` 的操作人员,返回 `true` 为需要拦截,返回 `false` 则表示不拦截,使用默认实现。
onReactionInfoTap: (context, model) {
return true;
},
);
}
通过arguments的构造主要用于路由跳转时,当uikit内部进行页面跳转时,可以通过 RouteSettings 得到 arguments,你可以对它进行赋值和定义,之后将它重新放到 RouteSettings 中并返回。 这样在跳转到的新页面就会按照你设置的 arguments 就行创建。 当然,也允许直接使用 arguments 进行页面构造,下面将介绍如何直接使用 arguments 进行构造和自定义。
MessagesViewArguments({
required this.profile,
this.controller,
this.appBar,
this.title,
this.inputBar,
this.showMessageItemAvatar,
this.showMessageItemNickname,
this.onItemTap,
this.onDoubleTap,
this.onAvatarTap,
this.onAvatarLongPress,
this.onNicknameTap,
this.emojiWidget,
this.itemBuilder,
this.alertItemBuilder,
this.morePressActions,
this.bubbleStyle = ChatUIKitMessageListViewBubbleStyle.arrow,
this.replyBarBuilder,
this.quoteBuilder,
this.onErrorBtnTapHandler,
this.bubbleBuilder,
this.enableAppBar = true,
this.bubbleContentBuilder,
this.onMoreActionsItemsHandler,
this.onItemLongPressHandler,
this.inputBarTextEditingController,
this.forceLeft,
this.multiSelectBottomBar,
this.viewObserver,
this.attributes,
this.onReactionItemTap,
this.onReactionInfoTap,
this.reactionItemsBuilder,
this.onThreadItemTap,
this.threadItemBuilder,
this.appBarTrailingActionsBuilder,
});
@override
// profile: 消息接收方的信息, 可以是 `ChatUIKitProfile.contact` 或者 `ChatUIKitProfile.group`
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
appBar: AppBar(title: const Text('test')),
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
enableAppBar: false,
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
title: 'Chat',
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
// defaultList: 默认的菜单项。
appBarTrailingActionsBuilder: (context, defaultList) {
return defaultList;
},
),
);
}
MessageListViewController
是 uikit 内部用来获取和操作数据用的控制器。
@override
Widget build(BuildContext context) {
final profile = ChatUIKitProfile.contact(id: chatter);
// 需要注意,构造 `MessageListViewController` 的 `profile` 要与构造 `MessagesView` 的一致。
final MessageListViewController controller = MessageListViewController(profile: profile);
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
controller: controller,
),
);
}
如果自定义输入框,需要将输入框内的文字通过 MessageListViewController
发送。
final TextEditingController textController = TextEditingController();
@override
Widget build(BuildContext context) {
final profile = ChatUIKitProfile.contact(id: chatter);
// 需要注意,构造 `MessageListViewController` 的 `profile` 要与构造 `MessagesView` 的一致。
final MessageListViewController controller = MessageListViewController(profile: profile);
return MessagesView.arguments(
MessagesViewArguments(
profile: profile,
controller: controller,
inputBar: Row(
children: [
Expanded(
child: TextField(
controller: textController,
),
),
InkWell(
onTap: () {
controller.sendTextMessage(textController.text);
textController.clear();
},
child: const SizedBox(
width: 40,
child: Text('Send'),
),
)
],
),
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
showMessageItemAvatar: (model) {
return false;
},
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
showMessageItemNickname: (model) {
return false;
},
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
// 如果你需要拦截点击事件返回 `true`, 如果你不处理,返回 `false`
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
onItemTap: (context, model) {
return false;
},
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
// 长按弹出菜单,返回 [] 则不弹出菜单
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息。
// defaultActions 默认的菜单项,包括了复制,删除等操作
onItemLongPressHandler: (context, model, defaultActions) {
return defaultActions;
},
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
// 如果你需要拦截点击事件返回 `true`, 如果你不处理,返回 `false`
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
onDoubleTap: (context, model) {
return false;
},
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
// 如果你需要拦截点击事件返回 `true`, 如果你不处理,返回 `false`
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
onAvatarTap: (context, model) {
return false;
},
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
// 如果你需要拦截点击事件返回 `true`, 如果你不处理,返回 `false`
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
onNicknameTap: (context, model) {
return false;
},
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
emojiWidget: Container(
height: 200,
color: Colors.red,
),
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
itemBuilder: (context, model) {
return ListTile(
title: Text(model.message.textContent),
);
},
),
);
}
提示消息主要是指 撤回消息,或者是加群之类的消息。
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
alertItemBuilder: (context, model) {
return const Text('XXX撤回了一条消息');
},
),
);
}
UIKit 提供了两种气泡样式,默认是 ChatUIKitMessageListViewBubbleStyle.arrow
。
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
bubbleStyle: ChatUIKitMessageListViewBubbleStyle.noArrow,
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
morePressActions: [
ChatUIKitBottomSheetItem.normal(label: 'take photo'),
],
),
);
}
也可以对 “更多” 按钮就行动态配置,当菜单弹出前才进行构建。
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
// defaultActions 默认要弹出的菜单,可以返回自己定义的菜单
onMoreActionsItemsHandler: (context, defaultActions) {
return defaultActions;
},
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
quoteBuilder: (context, model) {
return const Text('model.message');
},
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
// child: 消息内容 widget
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
bubbleBuilder: (context, child, model) {
return Container(
color: Colors.red,
padding: const EdgeInsets.all(8),
child: child,
);
},
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
// model 头像对应的消息数据,包括了消息的内容和消息的发送,接收方等信息
bubbleContentBuilder: (context, model) {
return const Text('自定义内容');
},
),
);
}
@override
Widget build(BuildContext context) {
return MessagesView(
profile: ChatUIKitProfile.contact(id: chatter),
forceLeft: true,
);
}
@override
Widget build(BuildContext context) {
return MessagesView.arguments(
MessagesViewArguments(
profile: ChatUIKitProfile.contact(id: chatter),
controller: controller,
multiSelectBottomBar: Row(
children: [
Expanded(
child: TextButton.icon(
onPressed: () {
if (controller.selectedMessages.isNotEmpty) {
// 跳转到 转发选择联系人页面
ChatUIKitRoute.pushOrPushNamed(
context,
ChatUIKitRouteNames.forwardMessageSelectView,
ForwardMessageSelectViewArguments(
messages: controller.selectedMessages,
isMulti: true,
),
).then((value) {
if (value == true) {
// 返回后需要关闭多选状态
controller.disableMultiSelectMode();
}
});
}
},
icon: const Icon(Icons.forward_10),
label: const Text('转发'),
),
)
],
),
),
);
}