如何在recyclerview或listview中的对话之间显示日期

时间:2015-09-30 13:48:48

标签: android android-recyclerview

如何显示日期或今天,昨天像对话之间的文字一样

像phatsapp一样

enter image description here

3 个答案:

答案 0 :(得分:4)

您需要为此目的创建一个新的ViewHolder

例如:

// 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

     }
}

答案 1 :(得分:4)

enter image description here

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(用于确定消息类型)

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用于解析分组聊天的日期

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用于当前用户消息

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用于显示其他用户消息。

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显示日期

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();
        }
    }

答案 2 :(得分:0)

您只需要在滚动时比较日期并设置日期视图的可见性即可。这样做的好处是,数据列表中的今天/昨天没有硬编码,并且能够在凌晨12点之后立即刷新(滚动)正确的日期。

例如在您的onBindViewHolder()中的recycleview中:

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

处理该日期视图的方法(假设您的列表格式为“ 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);
        }
    }
}

注意:如果您要追加新项目以重画图纸以在同一页面上凌晨12.00后取消以前的“今天” /日期,则还需要执行yourAdapter.notifyDataSetChanged();,而不仅仅是依靠{{ 1}},不会重新绘制以前的项目。