How to show calendar date at the top of chat messages?

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

Chat messages

Another timestamp image:

Timestamped Chat Messages

As you see in the example, the date is displayed on top of a new new batch of text messages. I would like to do the same, only for a series of posts related to a specific date. Say, if I have messages for October 19th, it shows October 19th from above, and then messages for October 20th, etc. Here is a working code example similar to mine:

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

, , , , , . , ", 19 2015 " ; , 19 , , . ? !

0
5

, / , . , . : , , : , timeview: TextView, TS ( ) :

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

}

, , - RecylcerView

+9

. ​​:

ListView
 - ListViewItem1
    - (TextView with date)
    - ListViewOfMsgsForThatDate
      a) Message1ForThisDate
      b) Message2ForThisDate
- ListViewItem2
   - (TextView with date)
   - ListViewOfMsgsForThatDate
      a) Message1ForThisDate
      b) Message2ForThisDate
+1

; , . , , . , . , .

, .

; , , , :)

, :

. , , . , , . ( [SQLite], , ). , .

public class ChatActivity extends ActionBarActivity {

    public static final String MyPREF = "MyPrefs" ;
    public static final String DATE_KEY = "DateKey" ;

    SharedPreferences prefs;
    SharedPreferences.Editor editor;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);
        initControls();
        pref = getSharedPreferences(MyPREF, MODE_PRIVATE);

        // Check that the shared preferences has a value
        if(contains(DATE_KEY)){
            editor = prefs.edit();
            // get the current datetime.
            editor.Long(DATE_KEY, date);
            editor.commit();
            // set the text of the textview android:id="@+id/date"
            // with the current formatted date.
        }

    }

onclick , - , , -, . , , , . .

sendBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        /.../
        }
        ChatMessage chatMessage = new ChatMessage();
        long LastDate = pref.getLong(DATE_KEY, date);
        // create an empty chat message with only a date.
        // check if the last used date is not today date.
        // if it not today date, save it and display it as
        // an archived bubble.
        if(!LastDate.isToday()){

            ChatMessage dateholder = new ChatMessage();
            // You'll need to format the date
            dateholder.setDate(Formatted LastDate);
            // set/change the text of the textview android:id="@+id/date"
            // with the current formatted date.

        }
        // put the current date time into your preferences.
        editor = prefs.edit();
        editor.putString(DATE_KEY, date);
        editor.commit();
        /.../
        // this is now setting up the new chat message.
        chatMessage.setDate(DateFormat.getDateTimeInstance().format(new Date()));
        /.../
        displayMessage(chatMessage);
    }
});

xml , , , . , , . , , ​​ .

.

<LinearLayout 
    android:layout_above="@+id/messageEdit"
    android:layout_below="@+id/meLbl"
    android:id="@+id/layout"
    .../orentation:vertical ../

<TextView
        android:id="@+id/date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true"
        /..//>

<ListView
    android:id="@+id/messagesContainer"
    .../

    ...//>

</LinearLayout>

    <TextView
        android:id="@+id/meLbl"
        /.../
        />

    <TextView
        android:id="@+id/friendLabel"
        /.../
         />

. . , , , , , .

:

public View getView(final int position, View convertView, ViewGroup parent)    {

    holder.txtMessage.setText(chatMessage.getMessage());
    // TODO, 
    // do a check if(mins are the same don't post 
    // else post the format without the date)
    // holder.txtInfo.setText(chatMessage.getDate());

.

, , , , . , , .

0

. . , , , , .

<?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="wrap_content"
    android:background="@android:color/white"
    android:orientation="vertical"
    android:padding="10dp">

    <LinearLayout
        android:id="@+id/timeTextLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="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>

ChatAdapter.java

public class ChatEGRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    public static class TextViewHolder extends RecyclerView.ViewHolder {
        public TextView textView;
        public LinearLayout timeText;
        public TextViewHolder(View v) {
            super(v);
            timeText = (LinearLayout) 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());

        //Group by Date
        long previousTs = 0;
        if(position >= 1){
            Message previousMessage = messages.get(position-1);
            previousTs = Long.parseLong(previousMessage.getSentTime());
        }
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTimeInMillis(Long.parseLong(messages.get(position).getSentTime())*1000);
        cal2.setTimeInMillis(previousTs*1000);
        boolean sameDay = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);
        if (!sameDay) {
            TextView dateView = new TextView(context);
            dateView.setText(messages.get(position).getSentTime());
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            params.gravity = Gravity.CENTER_HORIZONTAL;
            dateView.setLayoutParams(params);
            holder.timeText.addView(dateView);
        }
    }


    @Override
    public int getItemCount() {
        return messages.size();
    }

}

. , . . 24 , isNewGroup: true. , .

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

        if (messages.get(position).getIsNewGroup()) {
            TextView dateView = new TextView(context);
            dateView.setText(messages.get(position).getSentTime());
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            params.gravity = Gravity.CENTER_HORIZONTAL;
            dateView.setLayoutParams(params);
            holder.timeText.addView(dateView);
        }
    }  
0

Use this xml that helps to create the layout you are looking for according to your link - Designing Android Chat Bubble (Chat UI) offers.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
    android:id="@+id/content"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:orientation="vertical">

    <TextView
        android:id="@+id/txtDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:layout_gravity="right"
        android:textSize="12sp"
        android:textColor="@android:color/darker_gray" />

    <LinearLayout
        android:id="@+id/contentWithBackground"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:background="@drawable/your_msg_bubble_bg"
        android:paddingLeft="10dp"
        android:paddingBottom="10dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/txtMessage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/black"
            android:maxWidth="240dp" />

    </LinearLayout>

</LinearLayout>

enter image description here

I am updating this code for datetexview: -

<TextView
        android:id="@+id/txtDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:layout_gravity="right"
        android:textSize="12sp"
        android:textColor="@android:color/darker_gray" />
-1
source

Source: https://habr.com/ru/post/1609642/


All Articles