Whatsapp Message Layout - How to get time-view in the same row
Adding HTML non-breaking spaces did the trick. Tested the code on most devices and working absolutely fine. Maybe whatsapp is also doing the same thing. Below is the chat code:
See images below to see it working.
XML Design:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rel_layout_left"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/txtDate"
android:visibility="visible"
android:orientation="vertical"
>
<TextView
android:id="@+id/lblMsgFrom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="kfhdjbh"
android:textColor="@color/lblFromName"
android:textSize="12dp"
android:textStyle="italic"
android:visibility="gone" />
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/lblMsgFrom"
android:layout_marginRight="-5dp"
android:src="@drawable/bubble_corner" />
<FrameLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="@drawable/bg_msg_from"
android:layout_toRightOf="@+id/imageView">
<TextView
android:id="@+id/txtTimeFrom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="@dimen/d5"
android:text="Time"
android:textColor="@android:color/darker_gray"
android:layout_gravity="bottom|right"
android:padding="4dp"
android:textSize="10dp"
android:textStyle="italic"
android:layout_below="@+id/txtMsgFrom"
android:layout_alignRight="@+id/txtMsgFrom"
android:layout_alignEnd="@+id/txtMsgFrom" />
<TextView
android:id="@+id/txtMsgFrom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/imageView"
android:layout_toEndOf="@+id/lblMsgFrom"
android:layout_toRightOf="@+id/imageView"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="kdfjhgjfhf"
android:textColor="@color/black"
android:textSize="16dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="0dp"
android:layout_alignParentTop="true"
android:layout_marginTop="0dp"
android:layout_gravity="left|center_vertical" />
</FrameLayout>
</RelativeLayout>
Code: bg_msg_from.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- view background color -->
<!--<solid android:color="@color/bg_msg_from" >-->
<solid android:color="@android:color/white" >
</solid>
<corners android:radius="@dimen/d5" >
</corners>
</shape>
** File: bubble_corner.png**
txtMsgFrom.setText(Html.fromHtml(convertToHtml(txtMsgFrom.getText().toString()) + " ")); // 10 spaces
Position additional text inside UITextView - WhatsApp timestamp copy
To achieve the layout of WhatsApp chat row i.e. Message + Time, I had use following strategy.
Using 2 Label. 1st for Message and 2nd Date. For 1st I had constrainted view to top, bottom, left and right. For 2nd I had constraint it to right and bottom of View.
Now to avoid overlapping of 1st and 2nd I had appended "blank spaces" at the end of chat message. For example, if the message was "Hi"
I made it to "Hi "
. This ensure my Time and ticks do not overlap.
Mimick whatsapp messages layout in android
Haha, got it working at last, i was able to use uiautomatorviewer (suggested by CommonsWare) to view their structure.
It turns out i has to implement a custom adapter in addition to a Listview to get it working, here's the code in case anyone is interested.
MessageAdapter.java
package com.example.mestchat.Adapter;
/**
* Created by elimence on 6/1/13.
*/
import java.util.List;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.example.mestchat.MessageData;
import com.example.mestchat.R;
public class MessageAdapter extends ArrayAdapter {
private final Activity activity;
private final List messages;
public MessageAdapter(Activity activity, List objs) {
super(activity, R.layout.message_list , objs);
this.activity = activity;
this.messages = objs;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
MessageView msgView = null;
if(rowView == null)
{
// Get a new instance of the row layout view
LayoutInflater inflater = activity.getLayoutInflater();
rowView = inflater.inflate(R.layout.message_list, null);
// Hold the view objects in an object,
// so they don't need to be re-fetched
msgView = new MessageView();
msgView.msg = (TextView) rowView.findViewById(R.id.message_text);
// Cache the view objects in the tag,
// so they can be re-accessed later
rowView.setTag(msgView);
} else {
msgView = (MessageView) rowView.getTag();
}
// Transfer the stock data from the data object
// to the view objects
MessageData currentMsg = (MessageData)messages.get(position);
msgView.msg.setText(currentMsg.getMessage());
return rowView;
}
protected static class MessageView {
protected TextView msg;
}
}
MessageData.java
package com.example.mestchat;
/**
* Created by elimence on 6/1/13.
*/
public class MessageData {
private String message;
public MessageData(String message) {
this.message = message;
}
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
package com.example.mestchat;
import android.app.ListActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.*;
import com.example.mestchat.Adapter.MessageAdapter;
import com.example.mestchat.REST.RestWebServices;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends ListActivity {
MessageAdapter adapter;
List msgs;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
msgs = new ArrayList();
adapter = new MessageAdapter(this, msgs);
setListAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void sendMessage(View view) {
EditText message = (EditText) findViewById(R.id.enter_message);
String mText = message.getText().toString();
msgs.add(new MessageData(mText));
adapter.notifyDataSetChanged();
message.setText("");
}
}
message_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:gravity="fill_horizontal"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:layout_marginTop="@dimen/activity_horizontal_margin"
android:textColor="@color/black"
android:background="@color/white"
android:id="@+id/message_text" />
</RelativeLayout>
</LinearLayout>
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<!--<FrameLayout-->
<!--android:background="@color/header_color"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="0dp"-->
<!--android:layout_weight="1">-->
<!--</FrameLayout>-->
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="0dp"
android:layout_weight="10">
<FrameLayout
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="11">
<ListView
android:id="@android:id/list"
android:background="@drawable/background"
android:drawSelectorOnTop="false"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:footerDividersEnabled="true">
</ListView>
</FrameLayout>
<FrameLayout
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1">
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="@color/send_box_color"
android:id="@+id/linearLayout">
<EditText
android:id="@+id/enter_message"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:hint="@string/edit_text" />
<Button
android:id="@+id/send_button"
android:layout_width="45dp"
android:layout_height="30dp"
android:background="@drawable/send_btn"
android:onClick="sendMessage"/>
</LinearLayout>
</FrameLayout>
</LinearLayout>
</LinearLayout>
Related Topics
Image Share Intent Works for Gmail But Crashes Fb and Twitter
How to Add Android Support V7 Libraries in Eclipse
How to Kill Sub Activities and Bring Activity to Top of Stack
How to Link a Prebuilt Shared Library to an Android Ndk Project
Listening for Action_Screen_Off
Multiple Datepickers in Same Activity
Android Mediarecorder - "Start Failed: -19"
Firebase:Differencebetween Setpersistenceenabled and Keepsynced
What Is the Use of Movetofirst () in SQLite Cursors
Change Background Color of Android Menu
Firebase Onmessagereceived Not Called When App Is in the Background
Error 12501 Authenticating with Google Sign-In
Android Recyclerview Findviewholderforadapterposition Returns Null
Unzip a Zipped File on Sd Card in Android Application
Problem Inflating Custom View for Alertdialog in Dialogfragment