Failed to show the grouping date view for the chat messages in the recyclerview android

435 views Asked by At

How can I make the grouping and show the date view in my app. I am using recyclerview and java to show this messages

Structure:

   --------- **12-04-2021** ----------

--Leftsidemessage--
          ----rightsidemessgae----
--Leftsidemessage--
          ----rightsidemessgae----
--Leftsidemessage--
          ----rightsidemessgae----

    --------- **13-04-2021** ----------
--Leftsidemessage--
          ----rightsidemessgae----
--Leftsidemessage--
          ----rightsidemessgae----
--Leftsidemessage--
          ----rightsidemessgae----

The above is the message structure. I can able to show the rightside and leftside messages by the below code, But it failed to show the datetime view in my app.

Here how can I group and show the messages under a particular days message.

My Chat adapter code is here.

 @Override
        public int getItemViewType(int position) {
            Message message = (Message) msgDtoList.get(position);
            if (minemsg) {
                // If the current user is the sender of the message
                return VIEW_TYPE_MESSAGE_SENT;
            }
            if (!minemsg) {
                // If some other user sent the message
                return VIEW_TYPE_MESSAGE_RECEIVED;
            }
    
            if (message.getmSentTime() != "") { // here the message senttime is always print inside this condition. But failed to show the view in the app.
                return DATE_VIEW_TYPE;
            }
    
            return 0;
        }
     @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);
    
            }
            if (viewType == VIEW_TYPE_MESSAGE_RECEIVED) {
                view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.receiver_message_layout, parent, false);
                return new ReceiverMessageHolder(view);
            }
    
            if (viewType == DATE_VIEW_TYPE) {
                view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.date_view, parent, false);
                return new DateViewHolder(view);
            }
    
            return null;
        }

 @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        Message message = (Message) msgDtoList.get(position);

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

            case DATE_VIEW_TYPE:
                populateDateViewHolder(holder, position);
                break;
        }
    }

My Chat fragment:

  @Override
    public void onViewCreated(View v, @Nullable Bundle b) {
        super.onViewCreated(v, b);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        linearLayoutManager.setStackFromEnd(true);
        linearLayoutManager.setSmoothScrollbarEnabled(true);
        linearLayoutManager.setReverseLayout(false);
        mRecyclerView.setLayoutManager(linearLayoutManager);

        int newMsgPosition = mAdapter.getItemCount();
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setAdapter(mAdapter);
}
2

There are 2 answers

6
CSmith On

As minemsg is either true or false, the code returning DATE_VIEW_TYPE would never be reached. i.e., follow this pseudo-code:

boolean minemsg = true;
if (minemsg)
{
  return;
}
if (!minemsg)
{
  return;
}
// anything after this would never be reached!, as minemsg is either true or false.

Its not clear from your question what minemsg is, please try changing the order of evaluation as follows:

    @Override
    public int getItemViewType(int position) {
        Message message = (Message) msgDtoList.get(position);
        
        // check for date record first
        if (message.getmSentTime() != "") { // here the message senttime is always print inside this condition. But failed to show the view in the app.
            return DATE_VIEW_TYPE;
        }

        if (minemsg) {
            // If the current user is the sender of the message
            return VIEW_TYPE_MESSAGE_SENT;
        }
        if (!minemsg) {
            // If some other user sent the message
            return VIEW_TYPE_MESSAGE_RECEIVED;
        }

        
        return 0;
    }

EDIT: After reading your comments below, your problems are much deeper, you're trying to display a single ArrayList of messages with section/group headers.

This is beyond the scope of the question you asked, and appears to already have answers, e.g.:

How to implement RecyclerView with section header depending on category?

6
Shark On

Try this:

 @Override
        public int getItemViewType(int position) {
            Message message = (Message) msgDtoList.get(position);
    
            // Since message can either be "mine" or "not mine" lets check the sent time first, and return the DATE_VIEW_TYPE to avoid dead code
            if (message.getmSentTime() != "") { // here the message senttime is always print inside this condition. But failed to show the view in the app.
                return DATE_VIEW_TYPE;
            }

            if (minemsg) {
                // If the current user is the sender of the message
                return VIEW_TYPE_MESSAGE_SENT;
            }
            if (!minemsg) {
                // If some other user sent the message
                return VIEW_TYPE_MESSAGE_RECEIVED;
            }
            // Everything below is "dead, unreachable code" due to booleans being either true or false
    
            return 0;
        }