首页 > 解决方案 > 如何使用android java中的recyclerview实时接收聊天消息

问题描述

我已经使用 recyclerview 实现了聊天视图列表。但是列表没有实时向接收者显示消息。

如果我发送消息,接收者需要实时接收消息。我怎样才能使它起作用。

我对broadCastReceiver一无所知。在这里,我正在使用聊天屏幕。需要在我的应用程序中显示聊天消息。

问题是如果用户向我发送消息,我无法看到该消息。我需要通过 recyclerview 接收消息。

在我的聊天片段中:

  private RecyclerView mChatMessageRecyclerView;
    
     @Override
        public void onResume() {
            super.onResume();
            IntentFilter filter = new IntentFilter("Message_send");
            registerForContextMenu(mChatMessageRecyclerView);
        }
    
        @Override
        public void onPause() {
            super.onPause();
            unregisterForContextMenu(mChatMessageRecyclerView);
        }
    
        private final BroadcastReceiver mReceiverRecyclerview = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                mAdapter.notifyDataSetChanged();
                mAdapter.notifyItemInserted(getItemCount() + 1);
                mChatMessageRecyclerView.smoothScrollToPosition(getItemCount() + 1);
            }
        };
    
     LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
            
     @Override
        public void onViewCreated(View v, @Nullable Bundle b) {
            super.onViewCreated(v, b);
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
            linearLayoutManager.setStackFromEnd(true);
            linearLayoutManager.setSmoothScrollbarEnabled(true);
            linearLayoutManager.setReverseLayout(false);
         mChatMessageRecyclerView.setLayoutManager(linearLayoutManager);
            LocalBroadcastReceiver br = new LocalBroadcastReceiver() {
                @Override
                public void onReceiveIntent(@NonNull Context context, @NonNull Intent intent) {
                    mAdapter.notifyDataSetChanged();
                }
            };
            mChatMessageRecyclerView.getLayoutManager().smoothScrollToPosition(mChatMessageRecyclerView, new RecyclerView.State(), mChatMessageRecyclerView.getAdapter().getItemCount());
            
            int newMsgPosition = mAdapter.getItemCount();
            mChatMessageRecyclerView.setHasFixedSize(true);
            mChatMessageRecyclerView.setAdapter(mAdapter);
    }
    
     mSendMsg.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    String msgContent = mSendMsgInputBox.getText().toString();
    
                    if(!TextUtils.isEmpty(msgContent))
                    {
                        execute(new PostMessageRequest(message, Chatmessage.getmId(),

mPostMessageListener);
                    mSendMsgInputBox.setText("");
                }
            }
        });

我的适配器:

       private static final int VIEW_TYPE_MESSAGE_SENT = 1;
        private static final int VIEW_TYPE_MESSAGE_RECEIVED = 2;
        private List<MyMessageModel> msgDtoList; 
        MyMessageModel msgDto = this.msgDtoList.get(position);


         @Override
    public int getItemViewType(int position) {
        MyMessageModel message = (MyMessageModel) msgDtoList.get(position);

        if (message.getId().equals(Profile.getId())) {
            // If the current user is the sender of the message
            return VIEW_TYPE_MESSAGE_SENT;
        } else {
            // If some other user sent the message
            return VIEW_TYPE_MESSAGE_RECEIVED;
        }
    }

 @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view;

        if (viewType == VIEW_TYPE_MESSAGE_SENT) {
            view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.sender_message_layout, parent, false);
            return new SenderMessageHolder(view);

        } else if (viewType == VIEW_TYPE_MESSAGE_RECEIVED) {
            view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.receiver_message_layout, parent, false);
            return new ReceiverMessageHolder(view);
        }
    return null;
    }
             public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
                LastMessageContent message = (LastMessageContent) msgDtoList.get(position);

                switch (holder.getItemViewType()) {
                    case VIEW_TYPE_MESSAGE_SENT:
                        populateSentViewHolder(holder, position);   break;
                    case VIEW_TYPE_MESSAGE_RECEIVED:
                        populateReceivedViewHolder(holder, position);

                }

 @SuppressLint("ResourceAsColor")
    private void populateSentViewHolder(RecyclerView.ViewHolder holder, int position) {
        MyMessageModal msgDto = this.msgDtoList.get(position);
        ((SenderMessageHolder) holder).rightMsgTextView.setText(msgDto.getmMSg());
}

 @SuppressLint("ResourceAsColor")
    private void populateReceivedViewHolder(RecyclerView.ViewHolder holder, int position) {
        MyMessageModal msgDto = this.msgDtoList.get(position);
        ((ReceiverMessageHolder) holder).leftMsgTextView.setText(msgDto.getmMSg());
}

标签: androidandroid-recyclerviewadapter

解决方案


为了在您的 上显示实时数据,RecycleView您需要实现两件事:

  1. 监听实时数据的数据源。这可能来自例如WebSockets, Firebase, 一些消息队列等。
  2. 然后你需要通知你的适配器传入的消息,然后更新你的RecycleView. 您希望RecycleView在每次收到消息时仅使用新消息而不是整个列表来更新。为此,您将使用ListAdaptorand DiffUtil.ItemCallback。这是一个很好的教程,解释了如何管理RecycleView更新(用 Kotlin 解释):https ://developer.android.com/codelabs/kotlin-android-training-diffutil-databinding/#0

推荐阅读