gpt4 book ai didi

android - 如何在具有不同类型消息的聊天应用程序上组织 RecyclerView?

转载 作者:太空宇宙 更新时间:2023-11-03 13:40:09 26 4
gpt4 key购买 nike

我开发聊天应用程序,有不同类型的消息:简单文本、图像、文件等。也只有消息(其他,在屏幕左侧)和我的消息(在屏幕右侧)。

现在我对每种类型的消息都有不同的布局:

  • item_message_simple

  • item_my_message_simple

  • item_message_image

  • item_my_message_image

  • item_message_file

  • item_my_message_file

所有这些类型都在 RecyclerView.Adapter 中定义,并且在 getItemViewType() 中有许多 if-else 条件

还可以回复和转发具有更复杂布局的消息。如果我想添加新的消息类型,那将是一场灾难。

那么如何更好地组织它呢?也许它应该全部在一个布局和 2 种类型中:MESSAGE、MY_MESSAGE - 并显示/隐藏部分布局。或者再次输入 2 种类型(MESSAGE、MY_MESSAGE)并在 ViewHolder 中扩充所需的子布局。

请帮忙!

最佳答案

在我的例子中,我也有相同类型的消息选项,需要根据发件人消息和接收消息进行区分。我在根据消息类型自行创建 View 持有者时为发送者和接收者添加了不同的布局

每个消息都有不同的消息选项(文本、图像、视频、文件、音频等),我在 onBindViewHolder() 中处理了带有可见性显示和隐藏的开关盒。

我共有三个不同的 viewHolder。

YOU :您发送的消息(它应该始终显示在屏幕上)在您的情况下 MY_MESSAGE

其他:其他人发送的消息(它应该始终显示在屏幕上)在您的情况下 MESSAGE

TIMELINE:时间线消息,例如用户更改了聊天名称、删除了某某用户等

所以在这里,

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
MyViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());

switch (viewType) {
case YOU:
View v1 = inflater.inflate(R.layout.chat_right_layout, parent, false);
viewHolder = new MyViewHolder(v1, true);
break;
case OTHERS:
View v2 = inflater.inflate(R.layout.chat_left_layout, parent, false);
viewHolder = new MyViewHolder(v2, false);
break;
case TIMELINE:
View v3 = inflater.inflate(R.layout.chat_timeline_layout, parent, false);
viewHolder = new MyViewHolder(v3, false);
break;
}
return viewHolder;
}

这里我有 3 个不同的 xml 文件(您、其他人和 TimeLine 消息)每个 You 和其他 xml 布局都有分别包含文本、图像、PDF 的 View 。

@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
ChatModel model = mDataList.get(position);

if (model.getMessageType() == 10) // timeline message {
holder.mTvTimeLine.setText(DecodeUtil.decodeBase64(model.getMessageText())+" on "+date);
}else{
showTextAndMediaData(holder, model);
}
}

这是我为处理不同消息类型个人(您和其他人的文本图像等)而编写的逻辑。

 private void showTextAndMediaData(MyViewHolder myViewHolder, ChatModel model) {

switch (model.getMessageType()) {
case 1: // Image Type
myViewHolder.mTxtMsg.setVisibility(View.GONE);
myViewHolder.chatImageView.setVisibility(View.VISIBLE);
myViewHolder.videoLayout.setVisibility(View.GONE);
myViewHolder.documentImageView.setVisibility(View.GONE);

Uri mInitialUri = Uri.parse(model.getMessageText());
try {
myViewHolder.chatImageView.setImageURI(mInitialUri);
} catch (Exception e) {
e.printStackTrace();
}

break;
case 3: // video type
myViewHolder.mTxtMsg.setVisibility(View.GONE);
myViewHolder.chatImageView.setVisibility(View.GONE);
myViewHolder.videoLayout.setVisibility(View.VISIBLE);
myViewHolder.documentImageView.setVisibility(View.GONE);

Glide.with(mContext).load(Headers.getUrlWithHeaders(mContext, model.getThumbnailURL()))
.placeholder(R.drawable.novideo)
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(myViewHolder.vedioImageView);
}
break;
case 4:
case 5:
case 6:
case 7:
case 8:
case 9: // file type
myViewHolder.mTxtMsg.setVisibility(View.GONE);
myViewHolder.chatImageView.setVisibility(View.GONE);
myViewHolder.videoLayout.setVisibility(View.GONE);
myViewHolder.documentImageView.setVisibility(View.VISIBLE);

switch (model.getMediaType()) {
case "doc":
myViewHolder.documentImageView.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.img_word_document));
break;
case "pdf":
myViewHolder.documentImageView.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.img_pdf));
break;
case "excel":
myViewHolder.documentImageView.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.img_excel));
break;
case "ppt":
myViewHolder.documentImageView.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.img_ppt));
break;
case "txt":
myViewHolder.documentImageView.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.img_txt));
break;
case "csv":
myViewHolder.documentImageView.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.img_csv));
break;
default:
myViewHolder.documentImageView.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.img_otherdoc));
}
break;
default: // text type
myViewHolder.mTxtMsg.setVisibility(View.VISIBLE);
myViewHolder.chatImageView.setVisibility(View.GONE);
myViewHolder.videoLayout.setVisibility(View.GONE);
myViewHolder.documentImageView.setVisibility(View.GONE);

try {
myViewHolder.mTxtMsg.setText(text);
} catch (Exception e) {
e.printStackTrace();
myViewHolder.mTxtMsg.setText(text);
}

}
}

删除了一些案例逻辑,因为它们都是不同的类型并且以相同的方式处理。我还为发送者和接收者提供了更多逻辑,这些逻辑也已在此 block 中删除。您可以根据需要添加

是的,当你添加一个新的消息类型时,你需要在 onBindViewHolder 中再添加一个 case 来添加它。

希望它能提醒您完成任务。

关于android - 如何在具有不同类型消息的聊天应用程序上组织 RecyclerView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53826224/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com