定義聊天記錄佈局 msg_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:orientation="vertical"
android:padding="10dp">
<LinearLayout
android:id="@+id/left_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:background="@drawable/message_left"
>
<TextView
android:id="@+id/left_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#fff"/>
</LinearLayout>
<LinearLayout
android:id="@+id/right_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="@drawable/message_right"
>
<TextView
android:id="@+id/rigth_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#fff"/>
</LinearLayout>
</LinearLayout>
分別包含接收記錄(left_msg)以及發送記錄(right_msg)以及各自的背景圖片
定義主佈局 main_activity.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"
android:background="#d8e0e8"
android:orientation="vertical"
>
<ListView
android:id="@+id/msg_list_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:divider="#0000">
</ListView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/input_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Type somthing here"
android:maxLines="2"
/>
<Button
android:id="@+id/send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send"
/>
</LinearLayout>
</LinearLayout>
定義一個ListView 、輸入文本框以及發送按鈕
定義Msg類:
package com.example.uibestpractive;
public class Msg {
private String content; //消息的內容
private int type; //消息的類型
public static final int TYPE_RECEIVED = 0; //接收信息
public static final int TYPE_SEND = 1; //發送信息
public Msg (String content,int type){
this.content = content;
this.type = type;
}
public String getContent() {
return content;
}
public int getType() {
return type;
}
}
content 表示消息的內容,type表示消息的類型,消息的類型包含:TYPE_RECEIVED、TYPE_SEND。
創建ListView適配類,MsgAdapter:
package com.example.uibestpractive;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MsgAdapter extends ArrayAdapter<Msg>{
private int resourceId;
public MsgAdapter(Context context, int textViewResourceId, List<Msg> objects) {
super(context, textViewResourceId, objects);
// TODO Auto-generated constructor stub
resourceId = textViewResourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Msg msg = getItem(position);
View view ;
ViewHolder viewHolder = null;
if(convertView == null){
view = LayoutInflater.from(getContext()).inflate(resourceId, null);
viewHolder = new ViewHolder();
viewHolder.leftLayout = (LinearLayout)view.findViewById(R.id.left_layout);
viewHolder.rightLayout = (LinearLayout)view.findViewById(R.id.right_layout);
viewHolder.leftMsg = (TextView)view.findViewById(R.id.left_msg);
viewHolder.rightMsg = (TextView)view.findViewById(R.id.rigth_msg);
view.setTag(viewHolder);
}else{
view = convertView;
viewHolder = (ViewHolder)view.getTag();
}
if(msg.getType() == msg.TYPE_RECEIVED){ //如果是接收的信息,則顯示左邊的消息佈局,將右邊的消息佈局隱藏
viewHolder.leftLayout.setVisibility(View.VISIBLE);
viewHolder.rightLayout.setVisibility(View.GONE);
viewHolder.leftMsg.setText(msg.getContent());
}else if (msg.getType() == msg.TYPE_SEND){//如果是發送的信息,則顯示左邊的消息佈局,將右邊的消息佈局隱藏
viewHolder.rightLayout.setVisibility(View.VISIBLE);
viewHolder.leftLayout.setVisibility(View.GONE);
viewHolder.rightMsg.setText(msg.getContent());
}
return view ;
}
class ViewHolder{
LinearLayout leftLayout;
LinearLayout rightLayout;
TextView leftMsg;
TextView rightMsg;
}
}
在getView()方法中,通過消息的類型判斷 如果是收到的消息,則顯示左邊的消息佈局,如果是發送的消息,則顯示右邊的消息佈局。
MainActivity類:
package com.example.uibestpractive;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
public class MainActivity extends Activity implements OnClickListener{
private ListView msgListView;
private Button send;
private EditText inputText;
private MsgAdapter adapter;
private List<Msg> msgList = new ArrayList<Msg>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initMsgs();
adapter = new MsgAdapter(MainActivity.this, R.layout.msg_item, msgList);
send = (Button)findViewById(R.id.send);
inputText = (EditText)findViewById(R.id.input_text);
msgListView = (ListView)findViewById(R.id.msg_list_view);
msgListView.setAdapter(adapter);
send.setOnClickListener(this);
}
@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;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.quit) {
finish();
}
return super.onOptionsItemSelected(item);
}
private void initMsgs(){
Msg mgs1 = new Msg("hello guy", Msg.TYPE_RECEIVED);
msgList.add(mgs1);
Msg mgs2 = new Msg("hello, who is that ?", Msg.TYPE_SEND);
msgList.add(mgs2);
Msg msg3 = new Msg("This is tom.nick talking for you ",Msg.TYPE_RECEIVED);
msgList.add(msg3);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String content = inputText.getText().toString();
if(! "".equals(content)){
Msg msg = new Msg(content, Msg.TYPE_SEND);
msgList.add(msg);
adapter.notifyDataSetChanged(); //當有新消息時,刷新ListView 中的顯示
msgListView.setSelection(msgList.size()); //將ListView定位到最後一行
inputText.setText("");
}
}
}
當有信息發出時,如果content不為空,則創建一個新的Msg對象,並把它添加到msgList中,又調用notifyDataSetChanged()方法通知列表發生了變化,新增的消息才能在ListView中顯示,然後再調用setSelection()方法將顯示的數據定位在最後一行。