recyclerview personalizado android android-recyclerview recycler-adapter

personalizado - Cómo mostrar el día/fecha anterior de un grupo de elementos en Android RecyclerView



listview vs recyclerview (1)

Hola, estoy obteniendo datos en el JSONArray como:

{ "chatArray": [ { "msg_id": "193", "user_id": "15235", "first_name": "Vishal", "user_name": "vishal13", "message": "twilio", "chat_time": "2017-06-30 11:28:00" }, { "msg_id": "192", "user_id": "15321", "first_name": "Rohit", "user_name": "rohit12", "message": "how are you?", "chat_time": "2017-06-30 11:28:00" }]}

Estoy mostrando datos completos en un RecyclerView y ahora mi requisito es que quiero mostrar el encabezado de sus días anteriores como whatsapp.

public ChatScreenAdapter(Activity con, List<EquityDetails> list, String senderImage, String receiverImage) { this.items = list; this.context = con; this.senderImage = senderImage; this.receiverImage = receiverImage; this.arraylist = new ArrayList<EquityDetails>(); this.arraylist.addAll(items); if (con != null) { typeface_normal = Typeface.createFromAsset(con.getAssets(), "fonts/arial_regular.ttf"); share = context.getSharedPreferences("quiz_sharePrefs", 0); login_checked = share.getBoolean("ConfirmLogin", false); if (login_checked) { user_id = share.getInt("user_id", 0); } } } public static int getTimeRemaining(long timeStamp) { Calendar sDate = toCalendar(timeStamp); Calendar eDate = toCalendar(System.currentTimeMillis()); // Get the represented date in milliseconds long milis1 = sDate.getTimeInMillis(); long milis2 = eDate.getTimeInMillis(); // Calculate difference in milliseconds long diff = Math.abs(milis2 - milis1); return (int) (diff / (24 * 60 * 60 * 1000)); } private static Calendar toCalendar(long timestamp) { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(timestamp); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.advisory_left_side_chat_screen, parent, false); return new MyViewHolder(itemView); } @Override public void onBindViewHolder(final MyViewHolder holder, final int position) { final EquityDetails itemList = items.get(position); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); Glide.with(context).load(Constants.Profile_images + "" + senderImage).asBitmap().centerCrop().placeholder(R.drawable.default_usr).into(new BitmapImageViewTarget(holder.userImageViewRight) { @Override protected void setResource(Bitmap resource) { RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(context.getResources(), resource); circularBitmapDrawable.setCircular(true); holder.userImageViewRight.setImageDrawable(circularBitmapDrawable); } }); Glide.with(context).load(receiverImage + "").asBitmap().centerCrop().placeholder(R.drawable.default_usr).into(new BitmapImageViewTarget(holder.userImageViewLeft) { @Override protected void setResource(Bitmap resource) { RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(context.getResources(), resource); circularBitmapDrawable.setCircular(true); holder.userImageViewLeft.setImageDrawable(circularBitmapDrawable); } }); if (Integer.parseInt(itemList.getId()) == user_id) { holder.leftSideLayout.setVisibility(View.GONE); holder.rightSideLayout.setVisibility(View.VISIBLE); holder.messageTextViewRight.setText(itemList.getReviews_message() + ""); holder.nameTextViewRight.setText(itemList.getName()); holder.timeTvRight.setText(parseDateToddMMyyyy(itemList.getCreated_time())); } else { holder.leftSideLayout.setVisibility(View.VISIBLE); holder.rightSideLayout.setVisibility(View.GONE); holder.messageTextViewLeft.setText(itemList.getReviews_message() + ""); holder.nameTextViewLeft.setText(itemList.getName()); holder.timeTvLeft.setText(parseDateToddMMyyyy(itemList.getCreated_time())); } long previousTs = 0; if (position > 1) { if (getTimeRemaining(parseDay(itemList.getCreated_time())) == 0) holder.dayTextView.setText("Today"); else if (getTimeRemaining(parseDay(itemList.getCreated_time())) == 1) holder.dayTextView.setText("Yesterday"); else holder.dayTextView.setText("convert the date and show"); } } public long parseDay(String time) { // Make a Calendar whose DATE part is some time yesterday. Calendar cal = Calendar.getInstance(); cal.roll(Calendar.DATE, -1); String inputPattern = "yyyy-MM-dd HH:mm:ss"; String outputPattern = "dd MM"; SimpleDateFormat inputFormat = new SimpleDateFormat(inputPattern); Date date = null; String str = null; Date d = null; try { date = inputFormat.parse(time); if (date.before(cal.getTime())) { // myDate must be yesterday or earlier SimpleDateFormat outputFormat = new SimpleDateFormat(outputPattern); str = outputFormat.format(date); d = outputFormat.parse(str); } else { // myDate must be today or later SimpleDateFormat outputFormat = new SimpleDateFormat(outputPattern); str = outputFormat.format(date); d = outputFormat.parse(str); } } catch (ParseException e) { e.printStackTrace(); } return d.getTime(); } public String parseDateToddMMyyyy(String time) { // Make a Calendar whose DATE part is some time yesterday. Calendar cal = Calendar.getInstance(); cal.roll(Calendar.DATE, -1); String inputPattern = "yyyy-MM-dd HH:mm:ss"; String outputPattern = "dd MMM"; SimpleDateFormat inputFormat = new SimpleDateFormat(inputPattern); Date date = null; String str = null; try { date = inputFormat.parse(time); /* if (date.before(cal.getTime())) { // myDate must be yesterday or earlier SimpleDateFormat outputFormat = new SimpleDateFormat(outputPattern); str = outputFormat.format(date); } else {*/ // myDate must be today or later outputPattern = "hh:mm aa"; SimpleDateFormat outputFormat = new SimpleDateFormat(outputPattern); str = outputFormat.format(date); //} } catch (ParseException e) { e.printStackTrace(); } return str.toUpperCase(); } @Override public int getItemCount() { return items.size(); } public class MyViewHolder extends RecyclerView.ViewHolder { private RelativeLayout leftSideLayout; private RelativeLayout topLayoutLeft; private ImageView userImageViewLeft; private TextView nameTextViewLeft; private TextView staticTextViewLeft; private TextView messageTextViewLeft; private TextView timeTvLeft; private RelativeLayout rightSideLayout; private RelativeLayout topLayoutRight; private ImageView userImageViewRight; private TextView nameTextViewRight; private TextView staticTextViewRight; private TextView messageTextViewRight; private TextView timeTvRight; private TextView dayTextView; public MyViewHolder(View view) { super(view); leftSideLayout = (RelativeLayout) view.findViewById(R.id.left_side_layout); topLayoutLeft = (RelativeLayout) view.findViewById(R.id.top_layout_left); userImageViewLeft = (ImageView) view.findViewById(R.id.user_image_view_left); nameTextViewLeft = (TextView) view.findViewById(R.id.name_textView_left); staticTextViewLeft = (TextView) view.findViewById(R.id.static_textView_left); messageTextViewLeft = (TextView) view.findViewById(R.id.message_textView_left); timeTvLeft = (TextView) view.findViewById(R.id.time_tv_left); rightSideLayout = (RelativeLayout) view.findViewById(R.id.right_side_layout); topLayoutRight = (RelativeLayout) view.findViewById(R.id.top_layout_right); userImageViewRight = (ImageView) view.findViewById(R.id.user_image_view_right); nameTextViewRight = (TextView) view.findViewById(R.id.name_textView_right); staticTextViewRight = (TextView) view.findViewById(R.id.static_textView_right); messageTextViewRight = (TextView) view.findViewById(R.id.message_textView_right); timeTvRight = (TextView) view.findViewById(R.id.time_tv_right); dayTextView = (TextView) view.findViewById(R.id.day_textView); nameTextViewLeft.setTypeface(typeface_normal); nameTextViewRight.setTypeface(typeface_normal); messageTextViewLeft.setTypeface(typeface_normal); messageTextViewRight.setTypeface(typeface_normal); timeTvLeft.setTypeface(typeface_normal); timeTvRight.setTypeface(typeface_normal); dayTextView.setTypeface(typeface_normal); dayTextView.setVisibility(View.GONE); } }

Pero aquí dayTextView se muestra arriba de cada elemento, no según las fechas. Solo quiero mostrar cada fecha una vez en la parte superior de los mensajes correspondientes.


Actividad principal

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 (para determinar el tipo de mensaje)

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 para analizar la fecha para agrupar el 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 para el mensaje actual del usuario

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 para mostrar otros mensajes de usuario.

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 para mostrar la fecha

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