如何在聊天应用上组织不同类型的消息的循环查看? [英] How to organize RecyclerView on Chat App with different types of messages?

查看:52
本文介绍了如何在聊天应用上组织不同类型的消息的循环查看?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

现在,我对每种类型的邮件都有不同的布局:

  • Item_Message_Simple

  • Item_My_Message_Simple

  • Item_Message_Image

  • Item_My_Message_Image

  • Item_Message_FILE

  • Item_My_Message_FILE

所有这些类型都是在ReccyclerView.Adapter中定义的,并且getItemViewType()中有许多If-Else条件

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

那么如何更好地组织呢? 也许它应该全部包含在一个布局和两种类型中:Message、My_Message和显示/隐藏布局的各个部分。 或再次键入2个类型(MESSAGE、MY_MESSAGE)并在ViewHolder中膨胀所需的子布局。

请帮忙!

推荐答案

在我的情况下,我也有相同类型的邮件选项,需要根据发件人邮件和收到的邮件进行区分。我根据消息类型创建视图容器时,为发送者和接收者添加了不同的布局

每个MSG具有不同的消息选项(文本、图像、视频、文件、音频等),我处理onBindViewHolder()中的切换大小写,具有可见性显示和隐藏。

我总共有三个不同的取景器。

您:您发送的邮件(应始终显示在屏幕上)在您的案例中My_Message

其他:您的案例中由其他人发送的邮件(应始终显示在屏幕左侧)邮件

时间线:时间线消息,如用户更改聊天名称、删除so n so用户等

所以这里

@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文件(您、其他人和时间线消息) 您和其他每个XML版面都具有分别合并文本、图像和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中再添加一个案例才能添加它。

希望它能对您完成任务有所帮助。

这篇关于如何在聊天应用上组织不同类型的消息的循环查看?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆