How to show date in between conversation in recyclerview or in listview

前端 未结 3 366
一整个雨季
一整个雨季 2020-12-31 18:24

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

like whatsapp

相关标签:
3条回答
  • 2020-12-31 19:06

    MainActivity

    public class MainActivity extends AppCompatActivity {
    
        private ChatAdapter chatAdapter;
        private RecyclerView recyclerView;
        private Context context;
        private int loggedInUserID;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            bindRecyclerView();
            // TODO get logged in user id and initialize into 'loggedInUserID'
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            getData();
        }
    
        private void getData() {
            /**
             *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);
        }
    
        private void bindRecyclerView() {
            chatAdapter = new ChatAdapter(null);
            chatAdapter.setUser(loggedInUserID);
            RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
            recyclerView.setLayoutManager(mLayoutManager);
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            recyclerView.setAdapter(chatAdapter);
        }
    
    
        private void groupDataIntoHashMap(List<ChatModel> chatModelList) {
            LinkedHashMap<String, Set<ChatModel>> groupedHashMap = new LinkedHashMap<>();
            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 = new LinkedHashSet<>();
                    list.add(chatModel);
                    groupedHashMap.put(hashMapKey, list);
                }
            }
            //Generate list from map
            generateListFromMap(groupedHashMap);
    
        }
    
    
        private List<ListObject> generateListFromMap(LinkedHashMap<String, Set<ChatModel>> groupedHashMap) {
            // We linearly add every item into the consolidatedList.
            List<ListObject> consolidatedList = new ArrayList<>();
            for (String date : groupedHashMap.keySet()) {
                DateObject dateItem = new DateObject();
                dateItem.setDate(date);
                consolidatedList.add(dateItem);
                for (ChatModel chatModel : groupedHashMap.get(date)) {
                    ChatModelObject generalItem = new ChatModelObject();
                    generalItem.setChatModel(chatModel);
                    consolidatedList.add(generalItem);
                }
            }
    
            chatAdapter.setDataChange(consolidatedList);
    
            return consolidatedList;
        }
    
    }
    

    ChatModel.java

    public class ChatModel implements Serializable {
            private String messageId;
            private int userId;
            private String firstName;
            private String userName;
            private String message;
            private Date chatTime;
    
            //TODO generate getter and setter
    
        }
    

    ListObject.java (to determind the type of message)

    public abstract class ListObject {
            public static final int TYPE_DATE = 0;
            public static final int TYPE_GENERAL_RIGHT = 1;
            public static final int TYPE_GENERAL_LEFT = 2;
    
            abstract public int getType(int userId);
        }
    

    DateObject.java

    public class DateObject extends ListObject {
            private String date;
    
            public String getDate() {
                return date;
            }
    
            public void setDate(String date) {
                this.date = date;
            }
    
            @Override
            public int getType(int userId) {
                return TYPE_DATE;
            }
        }
    

    ChatModelObject.java

    public class ChatModelObject extends ListObject {
    
            private ChatModel chatModel;
    
            public ChatModel getChatModel() {
                return chatModel;
            }
    
            public void setChatModel(ChatModel chatModel) {
                this.chatModel = chatModel;
            }
    
            @Override
            public int getType(int userId) {
                if (this.chatModel.getUserId() == userId) {
                    return TYPE_GENERAL_RIGHT;
                } else
                    return TYPE_GENERAL_LEFT;
            }
        }
    

    DateParse.java to parse date for grouping the chat

    public class DateParser {
            private static DateFormat dateFormat1 = new SimpleDateFormat("dd/MM/yyyy");
    
            public static String convertDateToString(Date date) {
                String strDate = "";
                strDate = dateFormat1.format(date);
                return strDate;
            }
        }
    

    ChatAdapter.java

     public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    
            private List<ListObject> listObjects;
            private int loggedInUserId;
    
            public ChatAdapter(List<ListObject> listObjects) {
                this.listObjects = listObjects;
            }
    
            public void setUser(int userId) {
                this.loggedInUserId = userId;
            }
    
            public void setDataChange(List<ListObject> asList) {
                this.listObjects = asList;
                //now, tell the adapter about the update
                notifyDataSetChanged();
            }
    
            @Override
            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                RecyclerView.ViewHolder viewHolder = null;
                LayoutInflater inflater = LayoutInflater.from(parent.getContext());
                switch (viewType) {
                    case ListObject.TYPE_GENERAL_RIGHT:
                        View currentUserView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_chat_list_row_right, parent, false);
                        viewHolder = new ChatRightViewHolder(currentUserView); // view holder for normal items
                        break;
                    case ListObject.TYPE_GENERAL_LEFT:
                        View otherUserView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_chat_list_row_left, parent, false);
                        viewHolder = new ChatLeftViewHolder(otherUserView); // view holder for normal items
                        break;
                    case ListObject.TYPE_DATE:
                        View v2 = inflater.inflate(R.layout.date_row, parent, false);
                        viewHolder = new DateViewHolder(v2);
                        break;
                }
    
                return viewHolder;
    
            }
    
            @Override
            public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
                switch (viewHolder.getItemViewType()) {
                    case ListObject.TYPE_GENERAL_RIGHT:
                        ChatModelObject generalItem = (ChatModelObject) listObjects.get(position);
                        ChatRightViewHolder chatViewHolder = (ChatRightViewHolder) viewHolder;
                        chatViewHolder.bind(generalItem.getChatModel());
                        break;
                    case ListObject.TYPE_GENERAL_LEFT:
                        ChatModelObject generalItemLeft = (ChatModelObject) listObjects.get(position);
                        ChatLeftViewHolder chatLeftViewHolder = (ChatLeftViewHolder) viewHolder;
                        chatLeftViewHolder.bind(generalItemLeft.getChatModel());
                        break;
                    case ListObject.TYPE_DATE:
                        DateObject dateItem = (DateObject) listObjects.get(position);
                        DateViewHolder dateViewHolder = (DateViewHolder) viewHolder;
                        dateViewHolder.bind(dateItem.getDate());
                        break;
                }
            }
    
            @Override
            public int getItemCount() {
                if (listObjects != null) {
                    return listObjects.size();
                }
                return 0;
            }
    
            @Override
            public int getItemViewType(int position) {
                return listObjects.get(position).getType(loggedInUserId);
            }
    
            public ListObject getItem(int position) {
                return listObjects.get(position);
            }
        }
    

    ChatRightViewHolder.java for current user message

    public class ChatRightViewHolder extends RecyclerView.ViewHolder {
            private final String TAG = ChatRightViewHolder.class.getSimpleName();
    
            public ChatRightViewHolder(View itemView) {
                super(itemView);
                //TODO initialize your xml views
            }
    
            public void bind(final ChatModel chatModel) {
                //TODO set data to xml view via textivew.setText();
            }
        }
    

    ChatLeftViewHolder.java for display other user messages.

    public class ChatLeftViewHolder extends RecyclerView.ViewHolder {
            private final String TAG = ChatRightViewHolder.class.getSimpleName();
    
            public ChatLeftViewHolder(View itemView) {
                super(itemView);
                //TODO initialize your xml views
            }
    
            public void bind(final ChatModel chatModel) {
                //TODO set data to xml view via textivew.setText();
            }
        }
    

    DateViewHolder.java to display date

    public class DateViewHolder extends RecyclerView.ViewHolder {
            public DateViewHolder(View itemView) {
                super(itemView);
                //TODO initialize your xml views
            }
    
            public void bind(final String date) {
                //TODO set data to xml view via textivew.setText();
            }
        }
    
    0 讨论(0)
  • 2020-12-31 19:07

    You need to create a new ViewHolder for that purpose

    For example:

    // Different types of rows
    private static final int TYPE_ITEM_LEFT = 0;
    private static final int TYPE_ITEM_RIGHT = 1;
    private static final int TYPE_ITEM_DATE_CONTAINER = 2;
    
    public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    class ViewHolder0 extends RecyclerView.ViewHolder {
        // Viewholder for row type 0
    }
    
    class ViewHolder1 extends RecyclerView.ViewHolder {
        // Viewholder for row type 1
    }
    
    class ViewHolder2 extends RecyclerView.ViewHolder {
        // Viewholder for row type 2
    }
    
    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
         if (viewHolder.getItemViewType() == TYPE_ITEM_LEFT) {
             // Code to populate type 0 view here
    
         } else if (viewHolder.getItemViewType() == TYPE_ITEM_RIGHT) {
             // Code to populate type 1 view here
    
         } else if (viewHolder.getItemViewType() == TYPE_ITEM_DATE_CONTAINER) {
             // Code to populate type 2 view here
    
         }
    }
    
    0 讨论(0)
  • 2020-12-31 19:09

    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"):

       private void processDate(@NonNull TextView tv, String dateAPIStr
            , String dateAPICompareStr
            , boolean isFirstItem) {
    
        SimpleDateFormat f = new SimpleDateFormat("dd/MM/yyyy");
        if (isFirstItem) {
            //first item always got date/today to shows
            //and overkill to compare with next item flow
            Date dateFromAPI = null;
            try {
                dateFromAPI = f.parse(dateAPIStr);
                if (DateUtils.isToday(dateFromAPI.getTime())) tv.setText("today");
                else if (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");
                    else if (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.

    0 讨论(0)
提交回复
热议问题