天天看點

Android仿微信氣泡聊天界面設計(二)

微信的氣泡聊天是仿iPhone自帶短信而設計出來的,不過感覺還不錯可以嘗試一下仿着微信的氣泡聊天做一個Demo,給大家分享一下!效果圖如下:

Android仿微信氣泡聊天界面設計(二)

  氣泡聊天最終要的是素材,要用到9.png檔案的素材,這樣氣泡會随着聊天内容的多少而改變氣泡的大小且不失真。為了友善,我就直接在微信裡面提取出來啦。

  聊天的内容是用ListView來顯示的,将聊天的内容封裝成一個ChatMsgEntity類的對象裡面,然後交給自定義的ListView擴充卡将聊天内容顯示出來。

  ChatMsgEntity.java比較簡單,隻是聊天的内容存儲、設定和擷取。

[java] 
   ​​view plain​​​
   ​​​copy​​
1. package com.example.school;
2. 
3. public class ChatMsgEntity {
4. private static final String TAG = ChatMsgEntity.class.getSimpleName();
5. //名字
6. private String name;
7. //日期
8. private String date;
9. //聊天内容
10. private String text;
11. //是否為對方發來的資訊
12. private boolean isComMeg = true;
13. 
14. public String getName() {
15. return name;
16. }
17. 
18. public void setName(String name) {
19. this.name = name;
20. }
21. 
22. public String getDate() {
23. return date;
24. }
25. 
26. public void setDate(String date) {
27. this.date = date;
28. }
29. 
30. public String getText() {
31. return text;
32. }
33. 
34. public void setText(String text) {
35. this.text = text;
36. }
37. 
38. public boolean getMsgType() {
39. return isComMeg;
40. }
41. 
42. public void setMsgType(boolean isComMsg) {
43. isComMeg = isComMsg;
44. }
45. 
46. public ChatMsgEntity() {
47. }
48. 
49. public ChatMsgEntity(String name, String date, String text, boolean isComMsg) {
50. this.name = name;
51. this.date = date;
52. this.text = text;
53. this.isComMeg = isComMsg;
54. }
55. }      

  顯示ListView的擴充卡ChatMsgViewAdpater.java:

[java] 
   ​​view plain​​​
   ​​​copy​​ 
   
 
   
  
1. package com.example.school;
2. 
3. import android.R.integer;
4. import android.content.Context;
5. import android.database.DataSetObserver;
6. 
7. import android.util.Log;
8. import android.view.LayoutInflater;
9. import android.view.View;
10. import android.view.View.OnClickListener;
11. import android.view.View.OnLongClickListener;
12. import android.view.ViewGroup;
13. 
14. import android.widget.BaseAdapter;
15. import android.widget.CheckBox;
16. import android.widget.LinearLayout;
17. import android.widget.TextView;
18. 
19. import java.util.ArrayList;
20. import java.util.List;
21. 
22. public class ChatMsgViewAdapter extends BaseAdapter {
23. 
24. //ListView視圖的内容由IMsgViewType決定
25. public static interface IMsgViewType
26. {
27. //對方發來的資訊
28. int IMVT_COM_MSG = 0;
29. //自己發出的資訊
30. int IMVT_TO_MSG = 1;
31. }
32. 
33. private static final String TAG = ChatMsgViewAdapter.class.getSimpleName();
34. private List<ChatMsgEntity> data;
35. private Context context;
36. private LayoutInflater mInflater;
37. 
38. public ChatMsgViewAdapter(Context context, List<ChatMsgEntity> data) {
39. this.context = context;
40. this.data = data;
41. mInflater = LayoutInflater.from(context);
42. }
43. 
44. //擷取ListView的項個數
45. public int getCount() {
46. return data.size();
47. }
48. 
49. //擷取項
50. public Object getItem(int position) {
51. return data.get(position);
52. }
53. 
54. //擷取項的ID
55. public long getItemId(int position) {
56. return position;
57. }
58. 
59. //擷取項的類型
60. public int getItemViewType(int position) {
61. // TODO Auto-generated method stub
62. ChatMsgEntity entity = data.get(position);
63. 
64. if (entity.getMsgType())
65. {
66. return IMsgViewType.IMVT_COM_MSG;
67. else{
68. return IMsgViewType.IMVT_TO_MSG;
69. }
70. 
71. }
72. 
73. //擷取項的類型數
74. public int getViewTypeCount() {
75. // TODO Auto-generated method stub
76. return 2;
77. }
78. 
79. //擷取View
80. public View getView(int position, View convertView, ViewGroup parent) {
81. 
82. ChatMsgEntity entity = data.get(position);
83. boolean isComMsg = entity.getMsgType();
84. 
85. null;
86. if (convertView == null)
87. {
88. if (isComMsg)
89. {
90. //如果是對方發來的消息,則顯示的是左氣泡
91. null);
92. else{
93. //如果是自己發出的消息,則顯示的是右氣泡
94. null);
95. }
96. 
97. new ViewHolder();
98. viewHolder.tvSendTime = (TextView) convertView.findViewById(R.id.tv_sendtime);
99. viewHolder.tvUserName = (TextView) convertView.findViewById(R.id.tv_username);
100. viewHolder.tvContent = (TextView) convertView.findViewById(R.id.tv_chatcontent);
101. viewHolder.isComMsg = isComMsg;
102. 
103. convertView.setTag(viewHolder);
104. else{
105. viewHolder = (ViewHolder) convertView.getTag();
106. }
107. viewHolder.tvSendTime.setText(entity.getDate());
108. viewHolder.tvUserName.setText(entity.getName());
109. viewHolder.tvContent.setText(entity.getText());
110. 
111. return convertView;
112. }
113. 
114. //通過ViewHolder顯示項的内容
115. static class ViewHolder {
116. public TextView tvSendTime;
117. public TextView tvUserName;
118. public TextView tvContent;
119. public boolean isComMsg = true;
120. }
121. 
122. }      

  對方發來消息的顯示布局chatting_item_msg_text_left.xml

[html] 
   ​​view plain​​​
   ​​​copy​​ 
   
 
   
  
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:padding="6dp">
7. <LinearLayout
8. android:layout_width="fill_parent"
9. android:layout_height="wrap_content"
10. android:orientation="vertical"
11. android:gravity="center_horizontal">
12. <TextView
13. android:id="@+id/tv_sendtime"
14. android:layout_width="wrap_content"
15. android:layout_height="wrap_content"
16. style="@style/chat_text_date_style"/>
17. </LinearLayout>
18. <RelativeLayout
19. android:layout_width="fill_parent"
20. android:layout_height="wrap_content"
21. android:layout_marginTop="5dp" >
22. <ImageView
23. android:id="@+id/iv_userhead"
24. android:layout_width="wrap_content"
25. android:layout_height="wrap_content"
26. android:focusable="false"
27. android:layout_alignParentLeft="true"
28. android:layout_alignParentTop="true"
29. android:background="@drawable/mini_avatar_shadow"/>
30. <TextView
31. android:id="@+id/tv_chatcontent"
32. android:layout_toRightOf="@id/iv_userhead"
33. android:layout_marginLeft="10dp"
34. android:layout_width="wrap_content"
35. android:layout_height="wrap_content"
36. android:background="@drawable/chatfrom_bg"
37. style="@style/chat_content_date_style"/>
38. <TextView
39. android:id="@+id/tv_username"
40. android:layout_width="wrap_content"
41. android:layout_height="wrap_content"
42. android:layout_below="@id/iv_userhead"
43. android:layout_alignParentLeft="true"
44. android:layout_toLeftOf="@id/tv_chatcontent"
45. style="@style/chat_text_name_style"/>
46. </RelativeLayout>
47. </LinearLayout>      

  chatting_item_msg_text_right.xml和上面差不多,隻是氣泡和頭像的方向在右邊,就不貼代碼了。

  主界面的布局chat.xml

[html] 
   ​​view plain​​​
   ​​​copy​​ 
   
 
   
  
1. <?xml version="1.0" encoding="utf-8"?>
2. <RelativeLayout
3. xmlns:android="http://schemas.android.com/apk/res/android"
4. android:layout_width="fill_parent"
5. android:layout_height="fill_parent"
6. android:background="#f0f0e0" >
7. <RelativeLayout
8. android:id="@+id/rl_layout"
9. android:layout_width="fill_parent"
10. android:layout_height="wrap_content"
11. android:background="@drawable/title" >
12. <Button
13. android:id="@+id/btn_back"
14. android:gravity="center_vertical"
15. android:layout_marginLeft="5dp"
16. android:paddingLeft="18dp"
17. android:textSize="18.0sp"
18. android:textColor="#ffffff"
19. android:background="@drawable/selector_btn_back"
20. android:layout_width="70dp"
21. android:layout_height="wrap_content"
22. android:text="@string/back" />
23. <TextView
24. android:layout_width="wrap_content"
25. android:layout_height="wrap_content"
26. android:text="@string/school_title_name"
27. android:layout_centerInParent="true"
28. style="@style/my_txt"/>
29. <ImageView
30. android:layout_width="wrap_content"
31. android:layout_height="wrap_content"
32. android:background="@drawable/campus_info"
33. android:layout_centerVertical="true"
34. android:layout_alignParentRight="true"
35. android:layout_marginRight="15dp"/>
36. </RelativeLayout>
37. <RelativeLayout
38. android:id="@+id/rl_bottom"
39. android:layout_width="fill_parent"
40. android:layout_height="wrap_content"
41. android:layout_alignParentBottom="true"
42. android:background="@drawable/layout_bg1" >
43. <Button
44. android:id="@+id/btn_send"
45. android:layout_width="60dp"
46. android:layout_height="40dp"
47. android:layout_alignParentRight="true"
48. android:layout_marginRight="10dp"
49. android:layout_centerVertical="true"
50. android:text="@string/send" />
51. <EditText
52. android:id="@+id/et_sendmessage"
53. android:layout_width="fill_parent"
54. android:layout_height="40dp"
55. android:layout_toLeftOf="@id/btn_send"
56. android:layout_marginLeft="10dp"
57. android:layout_marginRight="10dp"
58. android:background="@drawable/edittext1"
59. android:layout_centerVertical="true"
60. android:singleLine="true"
61. android:textSize="18sp"/>
62. </RelativeLayout>
63. <ListView
64. android:id="@+id/listview"
65. android:layout_below="@id/rl_layout"
66. android:layout_above="@id/rl_bottom"
67. android:layout_width="fill_parent"
68. android:layout_height="fill_parent"
69. android:layout_marginLeft="10.0dip"
70. android:layout_marginTop="10.0dip"
71. android:layout_marginRight="10.0dip"
72. android:divider="@null"
73. android:dividerHeight="5dp"
74. android:scrollbars="none"
75. android:cacheColorHint="#00000000"/>
76. </RelativeLayout>      

  ChatActivity.java

[java] 
   ​​view plain​​​
   ​​​copy​​ 
   
 
   
  
1. package com.example.chat;
2. 
3. import java.util.ArrayList;
4. import java.util.Calendar;
5. import java.util.List;
6. 
7. import com.example.school.R;
8. 
9. import android.os.Bundle;
10. import android.app.Activity;
11. import android.content.Intent;
12. import android.view.KeyEvent;
13. import android.view.Menu;
14. import android.view.View;
15. import android.view.Window;
16. import android.view.View.OnClickListener;
17. import android.widget.AdapterView;
18. import android.widget.AdapterView.OnItemClickListener;
19. import android.widget.Button;
20. import android.widget.EditText;
21. import android.widget.ListView;
22. import android.widget.TextView;
23. 
24. public class ChatActivity extends Activity implements OnClickListener {
25. private Button mBtnSend;
26. private Button mBtnBack;
27. private EditText mEditTextContent;
28. //聊天内容的擴充卡
29. private ChatMsgViewAdapter mAdapter;
30. private ListView mListView;
31. //聊天的内容
32. private List<ChatMsgEntity> mDataArrays = new ArrayList<ChatMsgEntity>();
33. 
34. @Override
35. public void onCreate(Bundle savedInstanceState) {
36. super.onCreate(savedInstanceState);
37. // 去掉标題欄
38. setContentView(R.layout.chat);
39. initView();
40. initData();
41. }
42. 
43. //初始化視圖
44. private void initView() {
45. mListView = (ListView) findViewById(R.id.listview);
46. mBtnBack = (Button) findViewById(R.id.btn_back);
47. this);
48. mBtnSend = (Button) findViewById(R.id.btn_send);
49. this);
50. mEditTextContent = (EditText) findViewById(R.id.et_sendmessage);
51. }
52. 
53. private String[] msgArray = new String[]{"  孩子們,要好好學習,天天向上!要好好聽課,不要翹課!不要挂科,多拿獎學金!三等獎學金的争取拿二等,二等的争取拿一等,一等的争取拿勵志!",
54. "姚媽媽還有什麼吩咐...",
55. "還有,明天早上記得跑操啊,不來的就扣德育分!",
56. "德育分是什麼?扣了會怎麼樣?",
57. "德育分會影響獎學金評比,嚴重的話,會影響畢業",
58. "哇!學院那麼不人道?",
59. "你要是你不聽話,我當場讓你不能畢業!",
60. "姚媽媽,我知錯了(- -我錯在哪了...)"};
61. 
62. private String[]dataArray = new String[]{"2012-09-01 18:00", "2012-09-01 18:10",
63. "2012-09-01 18:11", "2012-09-01 18:20",
64. "2012-09-01 18:30", "2012-09-01 18:35",
65. "2012-09-01 18:40", "2012-09-01 18:50"};
66. private final static int COUNT = 8;
67. 
68. //初始化要顯示的資料
69. private void initData() {
70. for(int i = 0; i < COUNT; i++) {
71. new ChatMsgEntity();
72. entity.setDate(dataArray[i]);
73. if (i % 2 == 0)
74. {
75. "姚媽媽");
76. true);
77. else{
78. "Shamoo");
79. false);
80. }
81. 
82. entity.setText(msgArray[i]);
83. mDataArrays.add(entity);
84. }
85. new ChatMsgViewAdapter(this, mDataArrays);
86. mListView.setAdapter(mAdapter);
87. }
88. 
89. public void onClick(View view) {
90. // TODO Auto-generated method stub
91. switch(view.getId()) {
92. case R.id.btn_back:
93. back();
94. break;
95. case R.id.btn_send:
96. send();
97. break;
98. }
99. }
100. 
101. private void send()
102. {
103. String contString = mEditTextContent.getText().toString();
104. if (contString.length() > 0)
105. {
106. new ChatMsgEntity();
107. entity.setDate(getDate());
108. "");
109. false);
110. entity.setText(contString);
111. mDataArrays.add(entity);
112. mAdapter.notifyDataSetChanged();
113. "");
114. 1);
115. }
116. }
117. 
118. //擷取日期
119. private String getDate() {
120. Calendar c = Calendar.getInstance();
121. String year = String.valueOf(c.get(Calendar.YEAR));
122. String month = String.valueOf(c.get(Calendar.MONTH));
123. 1);
124. String hour = String.valueOf(c.get(Calendar.HOUR_OF_DAY));
125. String mins = String.valueOf(c.get(Calendar.MINUTE));
126. new StringBuffer();
127. "-" + month + "-" + day + " " + hour + ":" + mins);
128. return sbBuffer.toString();
129. }
130. public boolean onKeyDown(int keyCode, KeyEvent event) {
131. back();
132. return true;
133. }
134. 
135. private void back() {
136. finish();
137. }
138. }