Search code examples
androidandroid-layoutandroid-fragmentsandroid-activityandroid-date

How do I display the calendar date on the top of chat messages?


I am working on a chat application but I am struggling to figure out how to display the calendar date on the top of chat messages; for example, something like this:

Chat Messages

Another image with timestamps:

Chat Messages with Timestamps

As you see in the example, the date is displayed on top of a fresh new batch of text messages. I would like to do the same, just for a batch of messages related to a specific date. Say if I have messages for October 19, it shows October 19 on top followed by messages for October 20 and so on... Here's the working sample code similar to mine:

http://www.codeproject.com/Tips/897826/Designing-Android-Chat-Bubble-Chat-UI

The construction of the code is same as mine except for the date being displayed on top which is something I am stuck on. I have my timestamps showing for every message, I just want to display the date in the format "Monday, October 19, 2015" for the batch of messages; just once on top, from October 19, and likewise calendar dates for past and future messages, as shown in the image. Any clues? Thanks!


Solution

  • As far as I understand you want to show time/date only for certain group of messages and not for each message. So here is how to do that. Precondition: I assume each message item has time stamp based on which we will do our grouping Idea: we will need each list item to have timeview:TextView element and we will show and hide that element based on it's position and TS (time stamp) Example:

    item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:background="@color/white"
                  android:orientation="vertical"
                  android:padding="@dimen/padding_small">
    
        <TextView
            android:id="@+id/timeText"
            style="@style/DefaultText"
            android:paddingBottom="@dimen/padding_small"
            android:paddingRight="@dimen/padding_small"
            android:paddingTop="@dimen/padding_small"
            android:text="@string/hello_world"
            android:textSize="@dimen/font_size_small_10"/>
    
        <TextView
            android:id="@+id/textView"
            style="@style/DefaultText"
            android:layout_width="wrap_content"
            android:background="@drawable/bg_gray_rounded"
            android:paddingBottom="@dimen/padding_extra_small"
            android:paddingLeft="@dimen/padding_small"
            android:paddingRight="@dimen/padding_small"
            android:paddingTop="@dimen/padding_extra_small"
            android:textColor="@color/gray"
            android:textSize="@dimen/font_size_md"/>
    
    </LinearLayout>
    

    ChatRecyclerAdapter.java

    public class ChatEGRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    
        public static class TextViewHolder extends RecyclerView.ViewHolder {
            public TextView textView;
            public TextView timeText;
            public TextViewHolder(View v) {
                super(v);
                timeText = (TextView) v.findViewById(R.id.timeText);
                textView = (TextView) v.findViewById(R.id.textView);
            }
        }
    
        private final List<Message> messages;
    
    
        public ChatEGRecyclerAdapter(List<Message> messages) {
            this.messages = messages;
        }
    
    
        // Create new views (invoked by the layout manager)
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item, parent, false);
            return new TextViewHolder(v);
        }
    
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
            final Message m = messages.get(position);
            final Context context = viewHolder.itemView.getContext();
    
            TextViewHolder holder = (TextViewHolder)viewHolder;
            holder.textView.setVisibility(View.VISIBLE);
            holder.textView.setText(m.getText());
    
            long previousTs = 0;
            if(position>1){
                Message pm = messages.get(position-1);
                previousTs = pm.getTimeStamp();
            }
            setTimeTextVisibility(m.getTimeStamp(), previousTs, holder.timeText);
        }
    
        private void setTimeTextVisibility(long ts1, long ts2, TextView timeText){
    
            if(ts2==0){
                timeText.setVisibility(View.VISIBLE);
                timeText.setText(Utils.formatDayTimeHtml(ts1));
            }else {
                Calendar cal1 = Calendar.getInstance();
                Calendar cal2 = Calendar.getInstance();
                cal1.setTimeInMillis(ts1);
                cal2.setTimeInMillis(ts2);
    
                boolean sameMonth = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                        cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
    
                if(sameMonth){
                    timeText.setVisibility(View.GONE);
                    timeText.setText("");
                }else {
                    timeText.setVisibility(View.VISIBLE);
                    timeText.setText(Utils.formatDayTimeHtml(ts2));
                }
    
            }
        }
    
    
        @Override
        public int getItemCount() {
            return messages.size();
        }
    
    }
    

    what left is to create your RecylcerView and give it this adapter