简单模仿QQ聊天界面
首先看一下最终的效果,显示了消息时间,用户昵称,用户头像。
大致实现方法:
用最简单的ListView显示消息内容。
不同的用户使用不同的消息布局文件,从而达到头像左右显示的效果,如上图有2个用户"Tony","Hill",头像分别显示在左右两边。
代码文件清单:
主布局文件activity_main.xml:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:background="#ffffff" 6 tools:context=".MainActivity" > 7 <ListView 8 android:id="@+id/lv_message" 9 android:layout_height="fill_parent" 10 android:layout_width="fill_parent" 11 android:layout_above="@+id/ll_send_1" 12 android:scrollbars="none" 13 android:divider="@null" 14 android:footerDividersEnabled="false"> 15 </ListView> 16 <LinearLayout 17 android:id="@+id/ll_send_1" 18 android:layout_height="50dp" 19 android:layout_width="fill_parent" 20 android:orientation="horizontal" 21 android:layout_above="@+id/ll_send_2"> 22 <EditText 23 android:id="@+id/et_tony_message" 24 android:layout_width="0dp" 25 android:layout_height="fill_parent" 26 android:layout_weight="3" 27 android:hint="Tony请输入"/> 28 <Button 29 android:id="@+id/but_tony_send" 30 android:layout_height="fill_parent" 31 android:layout_width="0dp" 32 android:layout_weight="1" 33 android:text="send"/> 34 </LinearLayout> 35 <LinearLayout 36 android:id="@+id/ll_send_2" 37 android:layout_height="50dp" 38 android:layout_width="fill_parent" 39 android:orientation="horizontal" 40 android:layout_alignParentBottom="true"> 41 <EditText 42 android:id="@+id/et_hill_message" 43 android:layout_width="0dp" 44 android:layout_height="fill_parent" 45 android:layout_weight="3" 46 android:hint="Hill请输入"/> 47 <Button 48 android:id="@+id/but_hill_send" 49 android:layout_height="fill_parent" 50 android:layout_width="0dp" 51 android:layout_weight="1" 52 android:text="send"/> 53 </LinearLayout> 54 </RelativeLayout>
头像位于左边的消息布局文件list_message_item_left.xml:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="fill_parent" 4 android:layout_height="wrap_content" 5 android:orientation="vertical" 6 android:background="@drawable/chat_list_item_background" 7 android:padding="6dp"> 8 9 <LinearLayout 10 android:layout_width="fill_parent" 11 android:layout_height="wrap_content" 12 android:orientation="vertical" 13 android:gravity="center_horizontal"> 14 15 <TextView 16 android:id="@+id/tv_sendtime" 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:textColor="#8B8B8B" 20 android:textSize="12sp" 21 android:text="15:03:15"/> 22 </LinearLayout> 23 24 25 <RelativeLayout 26 android:layout_width="fill_parent" 27 android:layout_height="wrap_content"> 28 29 <ImageView 30 android:id="@+id/iv_userhead" 31 android:layout_width="40dp" 32 android:layout_height="40dp" 33 android:background="@drawable/head_portrait_1" 34 android:focusable="false" 35 android:layout_alignParentLeft="true" 36 android:layout_alignParentTop="true" /> 37 38 <TextView 39 android:id="@+id/tv_username" 40 android:layout_width="wrap_content" 41 android:layout_height="wrap_content" 42 android:layout_marginLeft="10dp" 43 android:layout_marginBottom="5dp" 44 android:textColor="#8B8B8B" 45 android:layout_toRightOf="@id/iv_userhead" 46 android:text="name"/> 47 48 <TextView 49 android:id="@+id/tv_chatcontent" 50 android:layout_toRightOf="@id/iv_userhead" 51 android:layout_marginLeft="10dp" 52 android:layout_marginRight="40dp" 53 android:layout_below="@id/tv_username" 54 android:layout_width="wrap_content" 55 android:layout_height="wrap_content" 56 android:text="" 57 android:background="@drawable/message_text_background01"/> 58 </RelativeLayout> 59 </LinearLayout>
头像位于右边的消息布局文件list_message_item_right.xml:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="fill_parent" 4 android:layout_height="wrap_content" 5 android:orientation="vertical" 6 android:background="@drawable/chat_list_item_background" 7 android:padding="6dp"> 8 9 <LinearLayout 10 android:layout_width="fill_parent" 11 android:layout_height="wrap_content" 12 android:orientation="vertical" 13 android:gravity="center_horizontal"> 14 15 <TextView 16 android:id="@+id/tv_sendtime" 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:textColor="#8B8B8B" 20 android:textSize="12sp" 21 android:text="15:03:15"/> 22 </LinearLayout> 23 <RelativeLayout 24 android:layout_width="fill_parent" 25 android:layout_height="wrap_content" 26 android:layout_marginTop="5dp" > 27 28 <ImageView 29 android:id="@+id/iv_userhead" 30 android:layout_width="40dp" 31 android:layout_height="40dp" 32 android:background="@drawable/head_portrait_2" 33 android:focusable="false" 34 android:layout_alignParentRight="true" 35 android:layout_alignParentTop="true" /> 36 37 <TextView 38 android:id="@+id/tv_username" 39 android:layout_width="wrap_content" 40 android:layout_height="wrap_content" 41 android:layout_marginRight="10dp" 42 android:layout_marginBottom="5dp" 43 android:textColor="#8B8B8B" 44 android:layout_toLeftOf="@id/iv_userhead" 45 android:text="name"/> 46 47 <TextView 48 android:id="@+id/tv_chatcontent" 49 android:layout_toLeftOf="@id/iv_userhead" 50 android:layout_marginRight="10dp" 51 android:layout_marginLeft="40dp" 52 android:layout_below="@id/tv_username" 53 android:layout_width="wrap_content" 54 android:layout_height="wrap_content" 55 android:text="" 56 android:background="@drawable/message_text_background02"/> 57 </RelativeLayout> 58 59 </LinearLayout>
主界面java代码文件MainActivity.java:
1 public class MainActivity extends Activity implements OnClickListener{ 2 EditText et_tony_message; 3 Button but_tony_send; 4 5 EditText et_hill_message; 6 Button but_hill_send; 7 8 ListView lv_message; 9 List<Message> list; 10 MessageAdapter adapter; 11 Handler handler=new Handler(); 12 @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.activity_main); 16 init(); 17 } 18 19 private void init() { 20 et_tony_message=(EditText) findViewById(R.id.et_tony_message); 21 but_tony_send=(Button) findViewById(R.id.but_tony_send); 22 but_tony_send.setOnClickListener(this); 23 24 et_hill_message=(EditText) findViewById(R.id.et_hill_message); 25 but_hill_send=(Button) findViewById(R.id.but_hill_send); 26 but_hill_send.setOnClickListener(this); 27 28 list=new ArrayList<Message>(); 29 lv_message=(ListView) findViewById(R.id.lv_message); 30 adapter=new MessageAdapter(); 31 lv_message.setAdapter(adapter); 32 } 33 34 35 @Override 36 public void onClick(View v) { 37 /*Tony发送消息*/ 38 if(v==but_tony_send){ 39 /*验证*/ 40 if(et_tony_message.getText()==null||et_tony_message.getText().toString().equals("")){ 41 Toast.makeText(this, "消息不能为空", 0).show(); 42 return ; 43 } 44 Message m=new Message(); 45 m.setFrom_username("Tony"); 46 m.setCreate_time(System.currentTimeMillis()); 47 m.setText(et_tony_message.getText().toString()); 48 sendMessage(m); 49 et_tony_message.setText(""); 50 } 51 /*Hill发送消息*/ 52 if(v==but_hill_send){ 53 /*验证*/ 54 if(et_hill_message.getText()==null||et_hill_message.getText().toString().equals("")){ 55 Toast.makeText(this, "消息不能为空", 0).show(); 56 return ; 57 } 58 Message m=new Message(); 59 m.setFrom_username("Hill"); 60 m.setCreate_time(System.currentTimeMillis()); 61 m.setText(et_hill_message.getText().toString()); 62 sendMessage(m); 63 et_hill_message.setText(""); 64 } 65 } 66 private void sendMessage(Message m) { 67 list.add(m); 68 adapter.notifyDataSetChanged(); 69 // lv_message.f 70 lv_message.setSelection(list.size()+1); 71 } 72 class MessageAdapter extends BaseAdapter{ 73 74 @Override 75 public int getCount() { 76 return list.size(); 77 } 78 79 @Override 80 public Object getItem(int position) { 81 return list.get(position); 82 } 83 84 @Override 85 public long getItemId(int position) { 86 return 0; 87 } 88 89 @Override 90 public View getView(int position, View convertView, ViewGroup parent) { 91 Message message=list.get(position); 92 ViewHolder viewHolder=null; 93 // if(convertView==null){ 94 if("Tony".equalsIgnoreCase(message.getFrom_username())){ 95 convertView=parent.inflate(MainActivity.this, R.layout.list_message_item_left, null); 96 }else{ 97 convertView=parent.inflate(MainActivity.this, R.layout.list_message_item_right, null); 98 } 99 viewHolder=new ViewHolder(); 100 viewHolder.iv_userhead=(ImageView) convertView.findViewById(R.id.iv_userhead); 101 viewHolder.tv_chatcontent=(TextView) convertView.findViewById(R.id.tv_chatcontent); 102 viewHolder.tv_sendtime=(TextView) convertView.findViewById(R.id.tv_sendtime); 103 viewHolder.tv_username=(TextView) convertView.findViewById(R.id.tv_username); 104 // convertView.setTag(viewHolder); 105 // }else{ 106 // viewHolder=(ViewHolder) convertView.getTag(); 107 // } 108 109 viewHolder.tv_chatcontent.setText(message.getText()); 110 viewHolder.tv_sendtime.setText(new SimpleDateFormat("HH:mm:ss").format(new Date(message.getCreate_time()))); 111 viewHolder.tv_username.setText(message.getFrom_username()); 112 return convertView; 113 } 114 class ViewHolder{ 115 public ImageView iv_userhead; 116 public TextView tv_username; 117 public TextView tv_chatcontent; 118 public TextView tv_sendtime; 119 } 120 } 121 }
消息封装代码文件Message.java:
1 public class Message { 2 private String from_username;/*发送者*/ 3 private Long create_time;/*发送时间*/ 4 private String text;/*消息内容*/ 5 public String getFrom_username() { 6 return from_username; 7 } 8 9 public Long getCreate_time() { 10 return create_time; 11 } 12 public void setCreate_time(Long create_time) { 13 this.create_time = create_time; 14 } 15 public String getText() { 16 return text; 17 } 18 public void setText(String text) { 19 this.text = text; 20 } 21 22 public void setFrom_username(String from_username) { 23 this.from_username = from_username; 24 } 25 26 }
源码下载:http://www.apkbus.com/forum.php?mod=viewthread&tid=173419&extra=