Android聊天机器人项目:如何在RecyclerView中添加两类消息视图
嘿,我来帮你搞定这个问题!要在RecyclerView里同时展示用户发送的消息和ChatBot的回复,核心思路就是区分不同的消息类型,让Adapter根据类型加载对应的布局并绑定数据。下面是一步步的具体操作:
1. 定义消息数据类
首先得创建一个能存储消息内容和类型的数据类,用来区分是用户消息还是机器人回复:
public class ChatMessage { private String content; private int messageType; // 定义类型常量,方便后续判断 public static final int TYPE_USER = 0; public static final int TYPE_BOT = 1; public ChatMessage(String content, int messageType) { this.content = content; this.messageType = messageType; } // Getter方法 public String getContent() { return content; } public int getMessageType() { return messageType; } }
2. 制作两种消息Item布局
需要两个不同的布局文件,分别对应用户消息(比如右对齐、特殊背景)和机器人回复(左对齐、另一款背景):
- 用户消息布局
item_user_msg.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end" android:background="@drawable/user_msg_bg" android:padding="10dp" android:layout_margin="8dp"> <TextView android:id="@+id/tv_user_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/white" android:textSize="16sp"/> </LinearLayout>
- 机器人回复布局
item_bot_msg.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="start" android:background="@drawable/bot_msg_bg" android:padding="10dp" android:layout_margin="8dp"> <TextView android:id="@+id/tv_bot_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/black" android:textSize="16sp"/> </LinearLayout>
注:user_msg_bg和bot_msg_bg可以是自定义的圆角矩形drawable,用来区分两种消息的视觉样式
3. 修改你的RecyclerViewAdapter
接下来改造Adapter,让它能识别并处理两种消息类型:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private static final String TAG = "RecyclerViewAdapter"; private ArrayList<ChatMessage> mChatList; public RecyclerViewAdapter(ArrayList<ChatMessage> chatList) { this.mChatList = chatList; } // 重写getItemViewType,返回当前位置消息的类型 @Override public int getItemViewType(int position) { return mChatList.get(position).getMessageType(); } // 创建两种ViewHolder,分别对应不同布局 public static class UserMsgHolder extends RecyclerView.ViewHolder { TextView userMsgTv; public UserMsgHolder(@NonNull View itemView) { super(itemView); userMsgTv = itemView.findViewById(R.id.tv_user_msg); } } public static class BotMsgHolder extends RecyclerView.ViewHolder { TextView botMsgTv; public BotMsgHolder(@NonNull View itemView) { super(itemView); botMsgTv = itemView.findViewById(R.id.tv_bot_msg); } } // 根据视图类型加载对应布局,返回对应ViewHolder @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); if (viewType == ChatMessage.TYPE_USER) { View view = inflater.inflate(R.layout.item_user_msg, parent, false); return new UserMsgHolder(view); } else { View view = inflater.inflate(R.layout.item_bot_msg, parent, false); return new BotMsgHolder(view); } } // 根据ViewHolder类型绑定对应数据 @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { ChatMessage currentMsg = mChatList.get(position); if (holder instanceof UserMsgHolder) { ((UserMsgHolder) holder).userMsgTv.setText(currentMsg.getContent()); } else if (holder instanceof BotMsgHolder) { ((BotMsgHolder) holder).botMsgTv.setText(currentMsg.getContent()); } } @Override public int getItemCount() { return mChatList.size(); } }
4. 在界面中添加消息并更新列表
最后,在你的聊天界面逻辑里,添加用户消息和机器人回复时,指定对应的类型即可:
// 添加用户发送的消息 mChatList.add(new ChatMessage("你好呀机器人!", ChatMessage.TYPE_USER)); mAdapter.notifyItemInserted(mChatList.size() - 1); // 自动滚动到底部 mRecyclerView.scrollToPosition(mChatList.size() - 1); // 模拟ChatBot回复(实际调用你的ChatBot模块获取内容后添加) new Handler().postDelayed(() -> { mChatList.add(new ChatMessage("你好呀!有什么可以帮你的?", ChatMessage.TYPE_BOT)); mAdapter.notifyItemInserted(mChatList.size() - 1); mRecyclerView.scrollToPosition(mChatList.size() - 1); }, 1000);
这样就能在RecyclerView里同时展示用户消息和ChatBot的回复,两种消息会用各自的布局样式显示啦!
内容的提问来源于stack exchange,提问作者Stefan Stef
相关产品推荐
相关产品推荐

