android - 如何在 recyclerView 中的两个不同项目之间显示不同的项目?
问题描述
我正在开发一个聊天应用程序,有两种类型的视图,一种用于传入消息,另一种用于传出消息。所以我通过视图类型将它们区分为 0 和 1。所以它工作得很好,但现在我想为日期添加另一个视图作为这样的标题。因此,为此,我将另一种视图类型设为 2,但它用消息视图替换了它。那么,如何在两个视图之间显示第三个视图?
这就是我创建ViewHolder
override fun onCreateViewHolder(parent: ViewGroup, position: Int): ViewHolder {
return if (position == 1) {
val view = LayoutInflater.from(mContext).inflate(R.layout.item_outgoing_message, parent, false)
ViewHolder(view)
} else if (position == 0) {
val view = LayoutInflater.from(mContext).inflate(R.layout.item_incoming_message, parent, false)
ViewHolder(view)
} else {
val view = LayoutInflater.from(mContext).inflate(R.layout.item_show_time_chat, parent, false)
ViewHolder(view)
}
}
这是我区分的方式ViewType
override fun getItemViewType(position: Int): Int {
return if (mChatList[position].getSender() == currentUserID) {
1
}
else if (mChatList[position].getMessageDate() == getTheRecentMessageDate(position)){
2
}
else {
0
}
}
这是为了得到日期之间的差异
private fun getTheRecentMessageDate(position: Int): String {
val lastMessagePosition = position - 1
//return the 1st message if messages chat thread is empty
val chat = mChatList[if (lastMessagePosition <= 0) 0 else lastMessagePosition]
//get and return the sender of the last message
return chat.getMessageDate()
}
最后将其应用于BindViewHolder
if (mChatList[position].getMessageDate() == getTheRecentMessageDate(position)){
holder.showDateTv?.text = getTheRecentMessageDate(position)
}
解决方案
您的适配器逻辑有缺陷,您需要定义从数据模型 ( mChatList
) 到 RecyclerView 的正确映射。
例如,如果您的聊天消息列表有两个条目,您需要一个三行的回收器。
这是一些粗略的伪代码,抱歉这是 Java,但你应该明白:
static final int VIEW_TYPE_SENDER = 0;
static final int VIEW_TYPE_TIMESTAMP = 1;
static final int VIEW_TYPE_REPLY = 2;
public int getItemCount()
{
// One row for each chat message + one row for each pair of messages.
// This logic possibly flawed for odd # of messages in mChatList
return (mChatList.size() + (mChatList.size() / 2);
}
public int getItemViewType (int position)
{
// modulo 3 to get the view type
switch (position % 3)
{
case 0:
return (VIEW_TYPE_SENDER);
case 1:
return (VIEW_TYPE_TIMESTAMP);
case 2:
return (VIEW_TYPE_REPLY);
}
}
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
switch (viewType)
{
case VIEW_TYPE_SENDER:
// return a Sender viewholder...
case VIEW_TYPE_REPLY:
// return a Reply viewholder...
case VIEW_TYPE_TIMESTAMP:
// return a timestamp viewholder...
}
}
}
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
if (holder instanceof SenderHolder)
{
int chatMessage = (position / 3);
// use mChatList[chatMessage] to get the data
}
else if (holder instanceof ReplyHolder)
{
int chatMessage = (position / 3) + 1;
// use mChatList[chatMessage] to get the data
}
...
}
请注意,这不考虑奇数的聊天消息,例如没有回复的发件人,这必须是正常的。这个答案有望为您指明正确的方向。
推荐阅读
- html - D3.js 多个 svg 事件未触发
- react-native - JSX 条件样式
- python-3.x - 如何创建一个包含 2 个相同模式之间的所有字符串的列表
- python - 如何将插入符号 (^) 传递给 selenium Web 驱动程序 send_keys() 方法
- python - 奇怪的日期格式化 YY-mm-dd 中的部分列和 YY-dd-mm 中的其余列
- javascript - Facebook Graph API 不适用于 UrlFetchApp
- c# - 在 WPF 中动态添加和删除 xaml 结构
- php - 如何在点击时从 $_SESSION 中删除特定数据
- azure-devops - 将自定义图像应用于使用自定义图像创建的现有 azure scaleset
- android - 在android/app/build.gradle(React Native ap)中动态填充一些数据