如何在 recyclerView 中的两个不同项目之间显示不同的项目?
Posted
技术标签:
【中文标题】如何在 recyclerView 中的两个不同项目之间显示不同的项目?【英文标题】:How to show a different item between two different items in a recyclerView? 【发布时间】:2021-08-15 17:38:27 【问题描述】:我正在开发一个聊天应用程序,有两种类型的视图,一种用于传入消息,另一种用于传出消息。所以我通过视图类型将它们区分为 0 和 1。所以它工作得很好,但现在我想为日期添加另一个视图作为标题,如 this。因此,为此,我将另一种视图类型设为 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
和回收站行之间的一对一映射
@CSmith 我知道并且我已经尝试过了,但是当我滑动消息回复时,日期视图也会随之滑动。
您的适配器需要表示您的聊天消息(例如 2 行)到您的 Recycler(例如 3 行)的映射。你的 onCreateViewHolder
、getItemViewType
和 onBindViewHolder
逻辑已经偏离了。
@CSmith 你能解释一下吗?
【参考方案1】:
您的适配器逻辑有缺陷,您需要定义从数据模型 (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
...
请注意,这不包括奇数条聊天消息,例如一个没有回复的发件人,这必须是正常的。这个答案有望为您指明正确的方向。
【讨论】:
以上是关于如何在 recyclerView 中的两个不同项目之间显示不同的项目?的主要内容,如果未能解决你的问题,请参考以下文章
如何在片段中的 recyclerView 上打开不同的活动?
如何通过单击 recyclerview 中的项目来打开新活动 [重复]
当 Recyclerview 在 NestedScrollview 中时,如何避免绑定所有项目?
Android TV 中的 RecyclerView 项目焦点