android-如何在聊天应用上使用不同类型的消息来组织RecyclerView?
作者:互联网
我开发了聊天应用程序,有不同类型的消息:简单的文本,图像,文件等.
也只有消息(其他在屏幕左侧)和我的消息(在屏幕右侧).
现在,每种消息类型都有不同的布局:
> 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条件
此外,消息可能会被转发和转发,其布局会更加复杂.
如果我想添加新的消息类型,那将是灾难.
那么如何组织更好的方法呢?
也许应该全部采用一种布局,并选择两种类型:MESSAGE,MY_MESSAGE-和显示/隐藏布局的一部分.
或再次输入2种类型(MESSAGE,MY_MESSAGE),然后在ViewHolder中填充所需的子布局.
请任何帮助!
解决方法:
就我而言,我也具有相同类型的消息选项,并且需要根据发件人消息和已接收消息进行区分.我根据消息类型自行创建了视图持有人,同时为发件人和接收人添加了不同的布局
每个味精具有不同的消息选项(文本,图像,视频,文件,音频等),我在onBindViewHolder()中使用开关大小写进行了显示和隐藏显示.
我在一起有三个不同的viewHolders.
YOU:您发送的邮件(应始终在屏幕上始终显示)就您的情况而言,MY_MESSAGE
其他:其他人发送的消息(应始终显示在屏幕左侧)
时间轴:时间轴消息,例如用户更改了聊天名称,已删除,因此用户等
所以在这里,
@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文件(您,其他和时间线消息)
每个You布局和其他xml布局都有分别合并Text,Image和PDF的视图.
@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);
}
}
}
删除了一些案例逻辑,因为它们都是不同的类型并以相同的方式处理.我还为发送方和接收方提供了更多逻辑,这些逻辑也在此块中删除.您可以根据需要添加
是的,当您添加新消息类型时,您需要在onBindViewHolder中再添加一个案例来添加它,这很困难.
希望它能帮助您完成任务.
标签:recycler-adapter,android-recyclerview,android-layout,chat,android 来源: https://codeday.me/bug/20191108/2007359.html