Skip to content Skip to sidebar Skip to footer

How To Show Date In Between Conversation In Recyclerview Or In Listview

How to show date or today , yesterday like text in between conversation like whatsapp

Solution 1:

enter image description here

MainActivity

publicclassMainActivityextendsAppCompatActivity {

    privateChatAdapter chatAdapter;
    privateRecyclerView recyclerView;
    privateContext context;
    private int loggedInUserID;

    @OverridepublicvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        bindRecyclerView();
        // TODO get logged in user id and initialize into 'loggedInUserID'
    }

    @OverrideprotectedvoidonResume() {
        super.onResume();
        getData();
    }

    privatevoidgetData() {
        /**
         *Your server call to get data and parse json to your appropriate model
         * after parsing json to model simply call the
         */List<ChatModel> chatModelList = ParseData.chatParser(jsonArray);
        groupDataIntoHashMap(chatModelList);
    }

    privatevoidbindRecyclerView() {
        chatAdapter = newChatAdapter(null);
        chatAdapter.setUser(loggedInUserID);
        RecyclerView.LayoutManager mLayoutManager = newLinearLayoutManager(context);
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(newDefaultItemAnimator());
        recyclerView.setAdapter(chatAdapter);
    }


    privatevoidgroupDataIntoHashMap(List<ChatModel> chatModelList) {
        LinkedHashMap<String, Set<ChatModel>> groupedHashMap = newLinkedHashMap<>();
        Set<ChatModel> list = null;
        for (ChatModel chatModel : chatModelList) {
            //Log.d(TAG, travelActivityDTO.toString());String hashMapKey = DateParser.convertDateToString(chatModel.getChatTime());
            //Log.d(TAG, "start date: " + DateParser.convertDateToString(travelActivityDTO.getStartDate()));if (groupedHashMap.containsKey(hashMapKey)) {
                // The key is already in the HashMap; add the pojo object// against the existing key.
                groupedHashMap.get(hashMapKey).add(chatModel);
            } else {
                // The key is not there in the HashMap; create a new key-value pair
                list = newLinkedHashSet<>();
                list.add(chatModel);
                groupedHashMap.put(hashMapKey, list);
            }
        }
        //Generate list from mapgenerateListFromMap(groupedHashMap);

    }


    privateList<ListObject> generateListFromMap(LinkedHashMap<String, Set<ChatModel>> groupedHashMap) {
        // We linearly add every item into the consolidatedList.List<ListObject> consolidatedList = newArrayList<>();
        for (String date : groupedHashMap.keySet()) {
            DateObject dateItem = newDateObject();
            dateItem.setDate(date);
            consolidatedList.add(dateItem);
            for (ChatModel chatModel : groupedHashMap.get(date)) {
                ChatModelObject generalItem = newChatModelObject();
                generalItem.setChatModel(chatModel);
                consolidatedList.add(generalItem);
            }
        }

        chatAdapter.setDataChange(consolidatedList);

        return consolidatedList;
    }

}

ChatModel.java

publicclassChatModelimplementsSerializable{
        privateString messageId;
        privateint userId;
        privateString firstName;
        privateString userName;
        privateString message;
        private Date chatTime;

        //TODO generate getter and setter

    }

ListObject.java (to determind the type of message)

publicabstractclassListObject {
        publicstaticfinalintTYPE_DATE=0;
        publicstaticfinalintTYPE_GENERAL_RIGHT=1;
        publicstaticfinalintTYPE_GENERAL_LEFT=2;

        abstractpublicintgetType(int userId);
    }

DateObject.java

publicclassDateObjectextendsListObject {
        privateString date;

        publicStringgetDate() {
            return date;
        }

        publicvoidsetDate(String date) {
            this.date = date;
        }

        @Overridepublic int getType(int userId) {
            returnTYPE_DATE;
        }
    }

ChatModelObject.java

publicclassChatModelObjectextendsListObject {

        private ChatModel chatModel;

        public ChatModel getChatModel() {
            return chatModel;
        }

        publicvoidsetChatModel(ChatModel chatModel) {
            this.chatModel = chatModel;
        }

        @OverridepublicintgetType(int userId) {
            if (this.chatModel.getUserId() == userId) {
                return TYPE_GENERAL_RIGHT;
            } elsereturn TYPE_GENERAL_LEFT;
        }
    }

DateParse.java to parse date for grouping the chat

publicclassDateParser {
        privatestaticDateFormat dateFormat1 = newSimpleDateFormat("dd/MM/yyyy");

        publicstaticStringconvertDateToString(Date date) {
            String strDate = "";
            strDate = dateFormat1.format(date);
            return strDate;
        }
    }

ChatAdapter.java

publicclassChatAdapterextendsRecyclerView.Adapter<RecyclerView.ViewHolder> {

        private List<ListObject> listObjects;
        privateint loggedInUserId;

        publicChatAdapter(List<ListObject> listObjects) {
            this.listObjects = listObjects;
        }

        publicvoidsetUser(int userId) {
            this.loggedInUserId = userId;
        }

        publicvoidsetDataChange(List<ListObject> asList) {
            this.listObjects = asList;
            //now, tell the adapter about the update
            notifyDataSetChanged();
        }

        @Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            RecyclerView.ViewHolderviewHolder=null;
            LayoutInflaterinflater= LayoutInflater.from(parent.getContext());
            switch (viewType) {
                case ListObject.TYPE_GENERAL_RIGHT:
                    ViewcurrentUserView= LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_chat_list_row_right, parent, false);
                    viewHolder = newChatRightViewHolder(currentUserView); // view holder for normal itemsbreak;
                case ListObject.TYPE_GENERAL_LEFT:
                    ViewotherUserView= LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_chat_list_row_left, parent, false);
                    viewHolder = newChatLeftViewHolder(otherUserView); // view holder for normal itemsbreak;
                case ListObject.TYPE_DATE:
                    Viewv2= inflater.inflate(R.layout.date_row, parent, false);
                    viewHolder = newDateViewHolder(v2);
                    break;
            }

            return viewHolder;

        }

        @OverridepublicvoidonBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
            switch (viewHolder.getItemViewType()) {
                case ListObject.TYPE_GENERAL_RIGHT:
                    ChatModelObjectgeneralItem= (ChatModelObject) listObjects.get(position);
                    ChatRightViewHolderchatViewHolder= (ChatRightViewHolder) viewHolder;
                    chatViewHolder.bind(generalItem.getChatModel());
                    break;
                case ListObject.TYPE_GENERAL_LEFT:
                    ChatModelObjectgeneralItemLeft= (ChatModelObject) listObjects.get(position);
                    ChatLeftViewHolderchatLeftViewHolder= (ChatLeftViewHolder) viewHolder;
                    chatLeftViewHolder.bind(generalItemLeft.getChatModel());
                    break;
                case ListObject.TYPE_DATE:
                    DateObjectdateItem= (DateObject) listObjects.get(position);
                    DateViewHolderdateViewHolder= (DateViewHolder) viewHolder;
                    dateViewHolder.bind(dateItem.getDate());
                    break;
            }
        }

        @OverridepublicintgetItemCount() {
            if (listObjects != null) {
                return listObjects.size();
            }
            return0;
        }

        @OverridepublicintgetItemViewType(int position) {
            return listObjects.get(position).getType(loggedInUserId);
        }

        public ListObject getItem(int position) {
            return listObjects.get(position);
        }
    }

ChatRightViewHolder.java for current user message

publicclassChatRightViewHolderextendsRecyclerView.ViewHolder {
        privatefinalStringTAG= ChatRightViewHolder.class.getSimpleName();

        publicChatRightViewHolder(View itemView) {
            super(itemView);
            //TODO initialize your xml views
        }

        publicvoidbind(final ChatModel chatModel) {
            //TODO set data to xml view via textivew.setText();
        }
    }

ChatLeftViewHolder.java for display other user messages.

publicclassChatLeftViewHolderextendsRecyclerView.ViewHolder {
        privatefinalStringTAG= ChatRightViewHolder.class.getSimpleName();

        publicChatLeftViewHolder(View itemView) {
            super(itemView);
            //TODO initialize your xml views
        }

        publicvoidbind(final ChatModel chatModel) {
            //TODO set data to xml view via textivew.setText();
        }
    }

DateViewHolder.java to display date

publicclassDateViewHolderextendsRecyclerView.ViewHolder {
        publicDateViewHolder(View itemView) {
            super(itemView);
            //TODO initialize your xml views
        }

        publicvoidbind(final String date) {
            //TODO set data to xml view via textivew.setText();
        }
    }

Solution 2:

You need to create a new ViewHolder for that purpose

For example:

// Different types of rowsprivatestaticfinalintTYPE_ITEM_LEFT=0;
privatestaticfinalintTYPE_ITEM_RIGHT=1;
privatestaticfinalintTYPE_ITEM_DATE_CONTAINER=2;

publicclassMyAdapterextendsRecyclerView.Adapter<RecyclerView.ViewHolder> {
classViewHolder0extendsRecyclerView.ViewHolder {
    // Viewholder for row type 0
}

classViewHolder1extendsRecyclerView.ViewHolder {
    // Viewholder for row type 1
}

classViewHolder2extendsRecyclerView.ViewHolder {
    // Viewholder for row type 2
}

@OverridepublicvoidonBindViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
     if (viewHolder.getItemViewType() == TYPE_ITEM_LEFT) {
         // Code to populate type 0 view here

     } elseif (viewHolder.getItemViewType() == TYPE_ITEM_RIGHT) {
         // Code to populate type 1 view here

     } elseif (viewHolder.getItemViewType() == TYPE_ITEM_DATE_CONTAINER) {
         // Code to populate type 2 view here

     }
}

Solution 3:

You just have to compare the date when scrolling and set the visibility of date view. The advantage of this is there's no hard-coded today/yesterday in data list and is able to refresh the correct date immediately (scrolling) after 12.00 a.m.

e.g. in your onBindViewHolder() in recycleview:

if (position != 0) {
            processDate(holder.topDateTextView, myData.getDate()
                    , this.myDataList.get(position - 1).getDate()
                    , false)
            ;
        } else {
            processDate(holder.topDateTextView, data.getDay()
                    , null
                    , true)
            ;
        }

Method to process that date view (Assume your list has format "dd/MM/yyyy"):

privatevoidprocessDate(@NonNull TextView tv, String dateAPIStr
        , String dateAPICompareStr
        , boolean isFirstItem) {

    SimpleDateFormat f = newSimpleDateFormat("dd/MM/yyyy");
    if (isFirstItem) {
        //first item always got date/today to shows//and overkill to compare with next item flowDate dateFromAPI = null;
        try {
            dateFromAPI = f.parse(dateAPIStr);
            if (DateUtils.isToday(dateFromAPI.getTime())) tv.setText("today");
            elseif (DateUtils.isToday(dateFromAPI.getTime() + DateUtils.DAY_IN_MILLIS)) tv.setText("yesterday");
            else tv.setText(dateAPIStr);
            tv.setIncludeFontPadding(false);
            tv.setVisibility(View.VISIBLE);
        } catch (ParseException e) {
            e.printStackTrace();
            tv.setVisibility(View.GONE);
        }
    } else {
        if (!dateAPIStr.equalsIgnoreCase(dateAPICompareStr)) {
            try {
                Date dateFromAPI = f.parse(dateAPIStr);
                if (DateUtils.isToday(dateFromAPI.getTime())) tv.setText("today");
                elseif (DateUtils.isToday(dateFromAPI.getTime() + DateUtils.DAY_IN_MILLIS)) tv.setText("yesterday");
                else tv.setText(dateAPIStr);
                tv.setIncludeFontPadding(false);
                tv.setVisibility(View.VISIBLE);
            } catch (ParseException e) {
                e.printStackTrace();
                tv.setVisibility(View.GONE);
            }
        } else {
            tv.setVisibility(View.GONE);
        }
    }
}

Note: You also need to do yourAdapter.notifyDataSetChanged(); if append new item to redraw to dismiss previous "today"/date after 12.00 a.m on the same page, not just rely on yourAdapter.notifyItemInserted(new_item_position) which doesn't redraw previous items.

Post a Comment for "How To Show Date In Between Conversation In Recyclerview Or In Listview"