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

Android 如何在recyclerview或listview中显示对话之间的日期,android,android-recyclerview,Android,Android Recyclerview,如何在对话之间显示日期或今天、昨天之类的文字 像whatsapp 为此,您需要创建一个新的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 MyA

如何在对话之间显示日期或今天、昨天之类的文字

像whatsapp


为此,您需要创建一个新的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

     }
}
//不同类型的行
私有静态最终整数类型\项\左=0;
私有静态最终整数类型\项\右=1;
私有静态最终整数类型\项目\日期\容器=2;
公共类MyAdapter扩展了RecyclerView.Adapter{
类ViewHolder0扩展了RecyclerView.ViewHolder{
//行类型0的Viewholder
}
类ViewHolder1扩展了RecyclerView.ViewHolder{
//行类型1的视图保持架
}
类ViewHolder2扩展了RecyclerView.ViewHolder{
//行类型2的视图保持架
}
@凌驾
public void onBindViewHolder(final RecyclerView.ViewHolder ViewHolder,int位置){
if(viewHolder.getItemViewType()=类型\u项目\u左){
//在此处填充类型0视图的代码
}else if(viewHolder.getItemViewType()=类型\u项目\u右侧){
//此处填充类型1视图的代码
}else if(viewHolder.getItemViewType()=类型\u项目\u日期\u容器){
//此处填充类型2视图的代码
}
}

主要活动

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

}
java(用于确定消息的类型)

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;
        }
    }
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;
        }
    }
ChatModelObject.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;
        }
    }
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;
        }
    }
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);
        }
    }
用于显示其他用户消息的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();
        }
    }

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

e、 g.在recycleview中的onBindViewHolder()中:

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


注意:如果将新项目附加到重画中以取消同一页面上先前的“今天”日期,则您还需要执行
yourAdapter.notifyDataSetChanged();
操作,而不仅仅依赖于
yourAdapter.notifyItemInserted(新项目位置)
不会重新绘制以前的项目。

check@ShahabRauf我在2015年9月30日提出了这个问题,您正在提供2015年10月20日提出的问题的链接。这不适合您,检查您的问题视图647次。这是针对与您面临相同问题的观众,如果他们阅读了您的问题,他们可以重定向通过我在这里写的链接找到答案。我希望你能understand@ShahabRauf很好:),但是这个问题在这里得到了回答,所以为什么要重定向到其他地方。这不是完整的答案,也许你和我可以通过给定的答案得到正确的答案,但是如果你打开链接,你会得到更好的答案。我正在开发一个聊天应用程序,看起来像什么pp和你的应用看起来一样你有这个应用的源代码吗?一直都很好的教程!非常有用的答案。Nice@akhilesh0707非常感谢,真的很有帮助
        if (position != 0) {
            processDate(holder.topDateTextView, myData.getDate()
                    , this.myDataList.get(position - 1).getDate()
                    , false)
            ;
        } else {
            processDate(holder.topDateTextView, data.getDay()
                    , null
                    , true)
            ;
        }
   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);
        }
    }
}