我先上效果图吧
1,manifest 我这里把默认弹出的软键盘关了 android:windowSoftInputMode="adjustUnspecified|stateHidden";
AndroidManifest.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.test.testim" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 7 <uses-sdk 8 android:minSdkVersion="8" 9 android:targetSdkVersion="16" /> 10 11 <application 12 android:allowBackup="true" 13 android:icon="@drawable/ic_launcher" 14 android:label="@string/app_name" 15 android:theme="@style/AppTheme" > 16 <activity 17 android:name="com.test.testim.MainActivity" 18 android:label="@string/app_name" 19 android:windowSoftInputMode="adjustUnspecified|stateHidden" > 20 <intent-filter> 21 <action android:name="android.intent.action.MAIN" /> 22 23 <category android:name="android.intent.category.LAUNCHER" /> 24 </intent-filter> 25 </activity> 26 </application> 27 28 </manifest>
2, 主界面的layout,这个没什么好讲的
main.xml
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:id="@+id/LinearLayout1" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:orientation="vertical" 7 tools:context=".MainActivity" > 8 9 <ListView 10 android:id="@+id/list" 11 android:layout_weight="19" 12 android:layout_width="fill_parent" 13 android:layout_height="0dp" 14 android:listSelector="@null" 15 android:transcriptMode="alwaysScroll" 16 android:cacheColorHint="#00000000" 17 android:divider="@null" 18 ></ListView> 19 20 <LinearLayout 21 android:orientation="horizontal" 22 android:gravity="center_vertical" 23 android:layout_width="fill_parent" 24 android:layout_height="wrap_content" 25 android:padding="10dp" 26 android:background="@android:color/darker_gray" 27 > 28 <ToggleButton 29 android:id="@+id/toggle" 30 android:textOn="From" 31 android:textOff="TO" 32 android:layout_width="wrap_content" 33 android:layout_height="wrap_content" 34 android:textSize="16sp" 35 /> 36 37 <EditText 38 android:id="@+id/edit" 39 android:layout_width="150dp" 40 android:layout_height="wrap_content" 41 android:textSize="18sp" 42 /> 43 <Button 44 android:id="@+id/send" 45 android:layout_marginLeft="20dp" 46 android:layout_width="wrap_content" 47 android:layout_height="wrap_content" 48 android:textSize="20sp" 49 android:text="发送" 50 /> 51 52 </LinearLayout> 53 </LinearLayout>
3,显示对方消息from的布局和自己消息to的布局
这里的布局用到一个特别需要注意的背景图片例如android:background="@drawable/chatfrom_bg_normal"
这里的chatfrom_bg_normal是chatfrom_bg_normal.9.png而不是chatfrom_bg_normal.png;
.9.png是是一种非失真性压缩位图图形文件格式,因为消息内容的多少会影响背景的失真,.9.png的制作工具在java的jdk、android的sdk中tools目录下的draw9patch.bat
我把这两个图片上传一下
item_from.xml
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="fill_parent" 3 android:layout_height="wrap_content" 4 android:paddingLeft="5dp" 5 android:paddingRight="5dp" 6 android:orientation="vertical" > 7 <TextView 8 android:id="@+id/time" 9 android:layout_width="fill_parent" 10 android:layout_height="wrap_content" 11 android:textSize="16sp" 12 android:background="@null" 13 android:layout_marginTop="10dp" 14 android:layout_marginBottom="5dp" 15 /> 16 <TextView 17 android:id="@+id/content" 18 android:paddingBottom="10dp" 19 android:layout_width="wrap_content" 20 android:layout_height="wrap_content" 21 android:textSize="16sp" 22 android:maxWidth="200dp" 23 android:background="@drawable/chatfrom_bg_normal" 24 /> 25 </LinearLayout>
item_to.xml
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="fill_parent" 3 android:layout_height="wrap_content" 4 android:paddingRight="5dp" 5 android:orientation="vertical" 6 android:gravity="right" > 7 <TextView 8 android:id="@+id/time" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:textSize="16sp" 12 android:background="@null" 13 android:layout_marginTop="10dp" 14 android:layout_marginBottom="5dp" 15 /> 16 <TextView 17 android:id="@+id/content" 18 android:layout_width="wrap_content" 19 android:layout_height="wrap_content" 20 android:maxWidth="200dp" 21 android:background="@drawable/chatto_bg_normal" 22 /> 23 </LinearLayout>
4,做一个消息的构造类
MessageVo
1 /** 2 * @Title: MessageVo.java 3 * @Package com.test.testim 4 * @Description: TODO(用一句话描述该文件做什么) 5 * @author Alex.Z 6 * @date 2013-2-27 上午11:23:17 7 * @version V1.0 8 */ 9 package com.test.testim; 10 11 public class MessageVo { 12 public static final int MESSAGE_FROM = 0; 13 public static final int MESSAGE_TO = 1; 14 15 private int direction; //该变量为消息是收到(MESSAGE_FROM)的还是发送(MESSAGE_TO)的 16 private String content; //内容 17 private String time; //时间 18 public MessageVo(int direction, String content, String time) { 19 super(); 20 this.direction = direction; 21 this.content = content; 22 this.time = time; 23 } 24 public int getDirection() { 25 return direction; 26 } 27 public String getContent() { 28 return content; 29 } 30 public String getTime() { 31 return time; 32 } 33 public void setDirection(int direction) { 34 this.direction = direction; 35 } 36 public void setContent(String content) { 37 this.content = content; 38 } 39 public void setTime(String time) { 40 this.time = time; 41 } 42 }
5,重写适配器
MessageAdapter
1 /** 2 * @Title: MessageAdapter.java 3 * @Package com.test.testim 4 * @Description: TODO(用一句话描述该文件做什么) 5 * @author Alex.Z 6 * @date 2013-2-27 下午12:05:50 7 * @version V1.0 8 */ 9 package com.test.testim; 10 11 import java.util.List; 12 13 import android.content.Context; 14 import android.view.LayoutInflater; 15 import android.view.View; 16 import android.view.ViewGroup; 17 import android.widget.BaseAdapter; 18 import android.widget.TextView; 19 20 public class MessageAdapter extends BaseAdapter{ 21 protected static final String TAG = "MessageAdapter"; 22 private Context context; 23 private List<MessageVo> messageVo; 24 25 26 public MessageAdapter(Context context, List<MessageVo> messageVo) { 27 super(); 28 this.context = context; 29 this.messageVo = messageVo; 30 } 31 32 33 @Override 34 public int getCount() { 35 // TODO Auto-generated method stub 36 return messageVo.size(); 37 } 38 39 40 @Override 41 public Object getItem(int position) { 42 // TODO Auto-generated method stub 43 return messageVo.get(position); 44 } 45 46 47 @Override 48 public long getItemId(int position) { 49 // TODO Auto-generated method stub 50 return position; 51 } 52 53 54 @Override 55 public View getView(int position, View convertView, ViewGroup parent) { 56 ViewHolder holder = null; 57 MessageVo message = messageVo.get(position); 58 if(convertView == null || (holder = (ViewHolder)convertView.getTag()).flag != message.getDirection()) 59 { 60 holder = new ViewHolder(); 61 if(message.getDirection() == MessageVo.MESSAGE_FROM) 62 { 63 holder.flag = MessageVo.MESSAGE_FROM; 64 convertView = LayoutInflater.from(context).inflate(R.layout.item_from, null); 65 } 66 else 67 { 68 holder.flag = MessageVo.MESSAGE_TO; 69 convertView = LayoutInflater.from(context).inflate(R.layout.item_to, null); 70 } 71 holder.content = (TextView)convertView.findViewById(R.id.content); 72 holder.time = (TextView)convertView.findViewById(R.id.time); 73 convertView.setTag(holder); 74 } 75 holder.content.setText(message.getContent()); 76 holder.time.setText(message.getTime()); 77 return convertView; 78 } 79 80 static class ViewHolder 81 { 82 int flag; 83 TextView content; 84 TextView time; 85 } 86 87 }
6, UI类
MainActivity
1 package com.test.testim; 2 3 import java.text.SimpleDateFormat; 4 import java.util.ArrayList; 5 import java.util.Date; 6 import java.util.List; 7 8 import android.app.Activity; 9 import android.os.Bundle; 10 import android.view.View; 11 import android.view.View.OnClickListener; 12 import android.widget.Button; 13 import android.widget.EditText; 14 import android.widget.ListView; 15 import android.widget.ToggleButton; 16 17 public class MainActivity extends Activity { 18 private ListView list; 19 private Button send; 20 private ToggleButton toggle; 21 private EditText edit; 22 private List<MessageVo> meList = new ArrayList<MessageVo>(); 23 private MessageAdapter messageAdapter = new MessageAdapter(this, meList);; 24 @Override 25 protected void onCreate(Bundle savedInstanceState) { 26 super.onCreate(savedInstanceState); 27 setContentView(R.layout.main); 28 29 initWidget(); 30 list.setAdapter(messageAdapter); 31 send.setOnClickListener(new OnClickListener() { 32 @Override 33 public void onClick(View v) { 34 String content = edit.getText().toString(); 35 String sendContent; 36 SimpleDateFormat df = new SimpleDateFormat("MM-dd HH:mm:ss"); 37 String time = df.format(new Date()).toString(); 38 System.out.println("time--------" + time); 39 if (content != null 40 && (sendContent = content.trim().replaceAll("\r", "").replaceAll("\t", "").replaceAll("\n", "") 41 .replaceAll("\f", "")) != "") 42 { 43 if(toggle.isChecked()) 44 { 45 meList.add(new MessageVo(MessageVo.MESSAGE_FROM, sendContent, time)); 46 } 47 else 48 { 49 meList.add(new MessageVo(MessageVo.MESSAGE_TO, sendContent, time)); 50 } 51 52 messageAdapter.notifyDataSetChanged(); 53 } 54 edit.setText(""); 55 } 56 }); 57 } 58 59 public void initWidget() 60 { 61 list = (ListView)findViewById(R.id.list); 62 send = (Button)findViewById(R.id.send); 63 edit = (EditText)findViewById(R.id.edit); 64 toggle = (ToggleButton)findViewById(R.id.toggle); 65 } 66 /** 67 * 消息设置 68 */ 69 // private void sendMessage(int direction,String content) 70 // { 71 // SimpleDateFormat df = new SimpleDateFormat("MM-dd HH:mm:ss"); 72 // String time = df.format(new Date()); 73 // if(direction == MessageVo.MESSAGE_FROM) 74 // { 75 // meList.add(new MessageVo(MessageVo.MESSAGE_FROM, content, time)); 76 // } 77 // else 78 // { 79 // meList.add(new MessageVo(MessageVo.MESSAGE_TO, content, time)); 80 // } 81 // messageAdapter.notifyDataSetChanged(); 82 // 83 // } 84 // 85 }