一個普通聊天頁面的ui,以下圖:android
##UI結構git
其中ListView的context layout 設計爲包含左右兩個TextView的設計,經過Adapter在顯示消息時決定使用layout的哪一個TextView顯示消息。github
左右兩個TextView背景圖(仿聊天氣泡)ide
##界面佈局(layout)佈局
**activity_main.xml **ui
主界面this
<?xml version="1.0" encoding="utf-8"?> <!--採用LinearLayout佈局 它包含的子控件將以橫向或豎向的方式排列 android:orientation="vertical" 垂直排列--> <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" android:paddingBottom="16dp" android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingTop="16dp" tools:context="study.zhukai.com.chatroom.MainActivity"> <!--ListView 該控件用來顯示聊天消息,須要實現一個Adapter類配合--> <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 Something" android:maxLines="2"/> <!--消息發送按鈕--> <Button android:id="@+id/send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Send"/> </LinearLayout> </LinearLayout>
msg_item.xml設計
ListView的content,實現消息放在聊天氣泡的效果code
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"> <!--位於左面的發送聊天氣泡,android:background="@drawable/chat_send_bubble" 選擇了聊天氣泡的圖片--> <LinearLayout android:id="@+id/left_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:background="@drawable/chat_send_bubble"> <TextView android:id="@+id/left_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="10dp" 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/chat_recv_bubble"> <TextView android:id="@+id/right_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="10dp" android:textColor="#fff"/> </LinearLayout> </LinearLayout>
##功能類實現xml
類結構
**MainActivity **
public class MainActivity extends Activity { private ListView msgListView; private EditText inputText; private Button send; private MsgAdapter adapter; private List<Msg> msgList =new ArrayList<Msg>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //去除標題框 requestWindowFeature(Window.FEATURE_NO_TITLE); //選擇佈局文件 setContentView(R.layout.activity_main); //初始化幾個消息 initMsgs(); adapter=new MsgAdapter(MainActivity.this,R.layout.msg_item,msgList); inputText = (EditText) findViewById(R.id.input_text); send =(Button) findViewById(R.id.send); msgListView =(ListView) findViewById(R.id.msg_list_view); msgListView.setAdapter(adapter); send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String content = inputText.getText().toString(); if(!"".equals(content)){ //設置消息類型(接受或發送) Msg msg =new Msg(content,Msg.TYPE_SENT); msgList.add(msg); //向adapter通知數據更新 adapter.notifyDataSetChanged(); //向adapter通知數據更新滾動到最新位置 msgListView.setSelection(msgList.size()); inputText.setText(""); } } }); } private void initMsgs(){ Msg msg1=new Msg("hello zhukai",Msg.TYPE_RECEIVED); Msg msg2=new Msg("nihao",Msg.TYPE_SENT); Msg msg3=new Msg("heihei",Msg.TYPE_RECEIVED); msgList.add(msg1); msgList.add(msg2); msgList.add(msg3); } }
Msg
public class Msg { public static final int TYPE_RECEIVED = 0; public static final int TYPE_SENT =1 ; private String content; private int type; public Msg(String content,int type){ this.content=content; this.type=type; } public String getContent(){ return content; } public int getType() { return type; } }
MsgAdapter
//ListView的配套Adapter類 public class MsgAdapter extends ArrayAdapter<Msg> { private int resourceId; //resourceId=ListView聊天氣泡佈局的xml文件id public MsgAdapter(Context context, int textViewResourceId, List<Msg> objects) { super(context, textViewResourceId, objects); resourceId= textViewResourceId; } //該方法決定在新消息到達後採用哪一種聊天氣泡顯示訊息 public View getView(int position, View convertView, ViewGroup parent) { Msg msg =getItem(position); View view; //自定義類 存放消息顯示位置參數 ViewHolder viewHolder; if(convertView==null){ //經過LayoutInflater的inflate方法制造顯示消息的view view = LayoutInflater.from(getContext()).inflate(resourceId,null); viewHolder=new ViewHolder(); //如下四句講view的控件賦給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.right_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_SENT){ 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; } }
代碼地址:https://github.com/madkilly/MyAndroidStudy chatroom moudle