上一篇说了欢迎和登陆界面的实现,现在来说一下关于聊天界面的搭建,整体界面采用了一个ListView,主要的布局很简单,在这里使用了ListView自定义是Adapter的写法
同时,我构造了一个TaliListInfo的类来和Adapter对应
闲话不多说,直接上代码
1 package com.demo.Adapter; 2 3 public class TalkListInfo { 4 5 private String name; 6 private String date; 7 private String item; 8 private int isNew; 9 10 public String getName() { 11 return name; 12 } 13 14 public void setName(String name) { 15 this.name = name; 16 } 17 18 public String getDate() { 19 return date; 20 } 21 22 public void setDate(String date) { 23 this.date = date; 24 } 25 26 public String getItem() { 27 return item; 28 } 29 30 public void setItem(String item) { 31 this.item = item; 32 } 33 34 public int getIsNew() { 35 return isNew; 36 } 37 38 public void setIsNew(int isNew) { 39 this.isNew = isNew; 40 } 41 42 public TalkListInfo() { 43 } 44 45 public TalkListInfo(String name, String date, String item, int isNew) { 46 this.name = name; 47 this.date = date; 48 this.isNew = isNew; 49 this.item = item; 50 } 51 52 }
Adapter的构造过程
package com.demo.Adapter; import java.util.List; import com.tuisong.R; import android.content.Context; import android.database.DataSetObserver; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.LinearLayout; import android.widget.TextView; public class NewAdapterView extends BaseAdapter { @SuppressWarnings("unused") private static final String TAG = NewAdapterView.class.getSimpleName(); private List<MessageEnity> coll; private Context context; // 构造函数 public NewAdapterView(Context context, List<MessageEnity> list) { this.context = context; this.coll = list; } public boolean areAllItemsEnabled() { return false; } public boolean isEnabled(int arg0) { return false; } @Override public int getCount() { // TODO Auto-generated method stub return coll.size(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return coll.get(arg0); } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return arg0; } public int getItemViewType(int position) { return position; } @Override public View getView(int positon, View convertView, ViewGroup parent) { // TODO Auto-generated method stub MessageEnity entity = coll.get(positon); int itemLayout = entity.getLayoutID(); LinearLayout layout = new LinearLayout(context); LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(itemLayout, layout, true); TextView tvName = (TextView) layout.findViewById(R.id.person_name); tvName.setText(entity.getfromUser()); TextView tvData = (TextView) layout.findViewById(R.id.time_say); tvData.setText(entity.getTime()); TextView tvItem = (TextView) layout.findViewById(R.id.item_say); tvItem.setText(entity.getItem()); return layout; } public int getViewTypeCount() { return coll.size(); } public boolean hasStableIds() { return false; } public boolean isEmpty() { return false; } public void registerDataSetObserver(DataSetObserver observer) { } public void unregisterDataSetObserver(DataSetObserver observer) { } }
同时,还需要写一个对应的布局来作为ListView的Adapter的布局
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:layout_width="fill_parent" 5 android:layout_height="wrap_content" 6 android:background="#eeeeee" 7 android:orientation="horizontal" 8 tools:context="com.baidu.push.example.CustomActivity" > 9 10 <ImageView 11 android:layout_width="64dp" 12 android:layout_height="64dp" 13 android:background="@drawable/retouxiang" 14 android:contentDescription="@string/app_name" 15 android:scaleType="fitXY" /> 16 17 <LinearLayout 18 android:layout_width="fill_parent" 19 android:layout_height="64dp" 20 android:orientation="vertical" > 21 22 <LinearLayout 23 android:layout_width="fill_parent" 24 android:layout_height="32dp" 25 android:orientation="horizontal" > 26 27 <TextView 28 android:id="@+id/tv_name" 29 android:layout_width="0dp" 30 android:layout_height="32dp" 31 android:layout_weight="1" 32 android:text="@string/app_name" 33 android:textColor="#000000" /> 34 35 <TextView 36 android:id="@+id/tv_time" 37 android:layout_width="0dp" 38 android:layout_height="32dp" 39 android:layout_weight="1" 40 android:text="@string/app_name" 41 android:textColor="#000000" /> 42 </LinearLayout> 43 44 <TextView 45 android:id="@+id/tv_item" 46 android:layout_width="fill_parent" 47 android:layout_height="32dp" 48 android:text="@string/app_name" 49 android:textColor="#000000" /> 50 </LinearLayout> 51 52 </LinearLayout>
同时,因为只是个Demo,我的头像没有下载的功能,采用了一个空白的头像图片,取消了下载功能,效果如图
同时,因为聊天记录保存在SQLite中,所以,需要自己实现一个DBhelper的类继承SQLiteOpenHelper,代码如下:
1 package com.tuisong.db; 2 3 import java.util.ArrayList; 4 import java.util.HashSet; 5 import java.util.List; 6 import com.demo.Adapter.MessageEnity; 7 import com.demo.Adapter.TalkListInfo; 8 9 import android.annotation.SuppressLint; 10 import android.content.ContentValues; 11 import android.content.Context; 12 import android.database.Cursor; 13 import android.database.sqlite.SQLiteDatabase; 14 import android.database.sqlite.SQLiteOpenHelper; 15 16 public class DBHelpter extends SQLiteOpenHelper { 17 18 private final static String DATABASE_NAME = "chat_record_db"; 19 private final static String TABLE_NAME = "chat_table"; 20 private final static String FROM_USER = "fromuser"; 21 private final static String TO_USER = "touser"; 22 private final static String TIME = "time"; 23 private final static String CHAT_CONTENT = "content"; 24 private final static String LAYOUT_ID = "layoutid"; 25 @SuppressWarnings("unused") 26 private final static String CHAT_ID = "id"; 27 private String openid = null; 28 public DBHelpter help; 29 30 @SuppressLint("NewApi") 31 public DBHelpter(Context context) { 32 super(context, DATABASE_NAME, null, 1); 33 System.out.println("the data has been created"); 34 // TODO Auto-generated constructor stub 35 } 36 37 @Override 38 public void onCreate(SQLiteDatabase db) { 39 // TODO Auto-generated method stub 40 String sql = "CREATE TABLE if not exists chat_table ( id INTEGER PRIMARY KEY AUTOINCREMENT, fromuser TEXT, touser TEXT, time TEXT, content TEXT, layoutid TEXT);"; 41 42 db.execSQL(sql); 43 System.out.println(sql); 44 } 45 46 //更新数据库,因为我没有数据的修改,所以不需要实现此方法 47 @Override 48 public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) { 49 // TODO Auto-generated method stub 50 // db.execSQL("drop table if exists" + TABLE_NAME); 51 52 // onCreate(db); 53 } 54 //插入数据 55 public void Insert(MessageEnity message) { 56 SQLiteDatabase db = this.getWritableDatabase(); 57 ContentValues value = new ContentValues(); 58 value.put(FROM_USER, message.getfromUser()); 59 value.put(TO_USER, message.gettomUser()); 60 value.put(TIME, message.getTime()); 61 value.put(CHAT_CONTENT, message.getItem()); 62 value.put(LAYOUT_ID, message.getLayoutID()); 63 64 long ss = db.insert(TABLE_NAME, null, value); 65 System.out.println("has been insert in db " + ss); 66 } 67 68 // 消息内容 69 public List<MessageEnity> findPersonMessage(String openid, String userid) { 70 List<MessageEnity> messages = new ArrayList<MessageEnity>(); 71 SQLiteDatabase db = this.getReadableDatabase(); 72 System.out.println("dsdfsw" + db.toString()); 73 74 String sql = "select * from chat_table where (fromuser=‘" + openid 75 + "‘ and touser=‘" + userid + "‘) or (touser=‘" + openid 76 + "‘ and fromuser=‘" + userid + "‘) order by time "; 77 Cursor cursor = db.rawQuery(sql, null); 78 cursor.moveToFirst(); 79 System.out.println("the find message is " + cursor.getCount()); 80 if (cursor.getCount() > 0) { 81 if (cursor.getCount() > 10) { 82 cursor.moveToPosition(cursor.getCount() - 10); 83 for (int i = 0; i < 10; i++) { 84 MessageEnity message = new MessageEnity(); 85 message.setfroUser(cursor.getString(cursor 86 .getColumnIndex(FROM_USER))); 87 message.setItem(cursor.getString(cursor 88 .getColumnIndex(CHAT_CONTENT))); 89 message.setLayoutID(cursor.getInt(cursor 90 .getColumnIndex(LAYOUT_ID))); 91 message.setTime(cursor.getString(cursor 92 .getColumnIndex(TIME))); 93 message.settoUser(cursor.getString(cursor 94 .getColumnIndex(TO_USER))); 95 messages.add(message); 96 cursor.moveToNext(); 97 } 98 } else { 99 cursor.moveToFirst(); 100 for (int i = 0; i < cursor.getCount(); i++) { 101 MessageEnity message = new MessageEnity(); 102 message.setfroUser(cursor.getString(cursor 103 .getColumnIndex(FROM_USER))); 104 message.setItem(cursor.getString(cursor 105 .getColumnIndex(CHAT_CONTENT))); 106 message.setLayoutID(cursor.getInt(cursor 107 .getColumnIndex(LAYOUT_ID))); 108 message.setTime(cursor.getString(cursor 109 .getColumnIndex(TIME))); 110 message.settoUser(cursor.getString(cursor 111 .getColumnIndex(TO_USER))); 112 messages.add(message); 113 cursor.moveToNext(); 114 } 115 } 116 return messages; 117 } else { 118 return null; 119 } 120 121 } 122 123 // 列出消息列表 124 public List<TalkListInfo> findList(String touser) { 125 List<TalkListInfo> infos = new ArrayList<TalkListInfo>(); 126 SQLiteDatabase db = this.getReadableDatabase(); 127 System.out.println("the ver sion is" + db.getVersion()); 128 String sql = "select fromuser, time , content,count(distinct fromuser) from chat_table where touser=‘" 129 + touser + "‘ group by fromuser order by time desc"; 130 // Cursor cursor = db.query(TABLE_NAME, new String[] { FROM_USER, TIME, 131 // CHAT_CONTENT }, null, null, null, null, TIME); 132 Cursor cursor = db.rawQuery(sql, null); 133 System.out.println("the ver num is" + cursor.getCount()); 134 cursor.moveToFirst(); 135 if (cursor.getCount() > 0) { 136 System.out.println("the tag num "); 137 for (int i = 0; i < cursor.getCount(); i++) { 138 139 if (cursor.getString(cursor.getColumnIndex(FROM_USER)).equals( 140 openid) != true) { 141 TalkListInfo info = new TalkListInfo(); 142 143 info.setName(cursor.getString(cursor 144 .getColumnIndex(FROM_USER))); 145 146 info.setDate(cursor.getString(cursor.getColumnIndex(TIME))); 147 info.setItem(cursor.getString(cursor 148 .getColumnIndex(CHAT_CONTENT))); 149 150 infos.add(info); 151 cursor.moveToNext(); 152 } 153 } 154 155 System.out.println("tag2"); 156 removeDuplicate(infos); 157 return infos; 158 } else { 159 System.out.println("tag3"); 160 return infos; 161 } 162 163 } 164 165 public static void removeDuplicate(List<TalkListInfo> list) { 166 HashSet<TalkListInfo> h = new HashSet<TalkListInfo>(list); 167 list.clear(); 168 list.addAll(h); 169 System.out.println(list); 170 } 171 172 }
好了到了这里,准备工作已经基本完成了,现在就要编写界面的后台代码了
1 package com.baidu.push.example; 2 3 import java.util.ArrayList; 4 import java.util.HashMap; 5 import java.util.List; 6 import java.util.Map; 7 8 import com.baidu.android.pushservice.PushConstants; 9 import com.baidu.android.pushservice.PushManager; 10 import com.demo.Adapter.ListAdapter; 11 import com.demo.Adapter.TalkListInfo; 12 import com.tuisong.R; 13 import com.tuisong.Save_Read; 14 import com.tuisong.Until; 15 import com.tuisong.db.DBHelpter; 16 17 import android.app.Activity; 18 import android.app.NotificationManager; 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.SharedPreferences; 23 import android.os.Bundle; 24 import android.view.Menu; 25 import android.view.MenuItem; 26 import android.view.View; 27 import android.widget.AdapterView.OnItemClickListener; 28 import android.widget.AdapterView; 29 import android.widget.ListView; 30 import android.widget.RelativeLayout; 31 32 public class PushDemoActivity extends Activity implements OnItemClickListener { 33 34 private static ListView list; 35 private static List<TalkListInfo> talk; 36 private static ListAdapter adapter; 37 RelativeLayout mainLayout = null; 38 public static int initialCnt = 0; 39 public Save_Read save = new Save_Read(); 40 public static Map<String, String> map; 41 public static DBHelpter help; 42 public static String userid; 43 public SharedPreferences sp; 44 public static NotificationManager manager; 45 46 @Override 47 public void onCreate(Bundle savedInstanceState) { 48 super.onCreate(savedInstanceState); 49 50 setContentView(R.layout.main); 51 @SuppressWarnings("unused") 52 NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 53 @SuppressWarnings("unused") 54 MyReceiver receiver = new MyReceiver(); 55 sp = this.getSharedPreferences("key", 0); 56 SharedPreferences.Editor edtior = sp.edit(); 57 edtior.putString("SSP", "1"); 58 edtior.commit(); 59 60 list = (ListView) findViewById(R.id.list); 61 help = new DBHelpter(this); 62 map = new HashMap<String, String>(); 63 64 userid = sp.getString("Login", null); 65 System.out.println("the login id is " + userid); 66 67 talk = new ArrayList<TalkListInfo>(); 68 69 talk = help.findList(userid); 70 71 if (talk != null) { 72 for (TalkListInfo t : talk) { 73 74 map.put("name", t.getName()); 75 map.put("time", t.getDate()); 76 map.put("content", t.getItem()); 77 } 78 adapter = new ListAdapter(this, talk); 79 list.setAdapter(adapter); 80 } 81 82 list.setOnItemClickListener(new OnItemClickListener() { 83 84 @Override 85 public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, 86 long arg3) { 87 // TODO Auto-generated method stub 88 Intent intent = new Intent(PushDemoActivity.this, 89 TalkActivity.class); 90 intent.putExtra("name", talk.get(arg2).getName()); 91 intent.putExtra("userid", userid); 92 Until.setString(talk.get(arg2).getName()); 93 startActivity(intent); 94 95 } 96 }); 97 98 // 以apikey的方式登录,一般放在主Activity的onCreate中 99 PushManager.startWork(getApplicationContext(), 100 PushConstants.LOGIN_TYPE_API_KEY, 101 Utils.getMetaValue(PushDemoActivity.this, "api_key")); 102 103 } 104 105 @Override 106 public void onStart() { 107 super.onStart(); 108 109 } 110 111 @Override 112 public void onResume() { 113 super.onResume(); 114 115 SharedPreferences.Editor edtior = sp.edit(); 116 edtior.putString("SSP", "0"); 117 edtior.commit(); 118 119 } 120 121 @Override 122 protected void onNewIntent(Intent intent) { 123 // 如果要统计Push引起的用户使用应用情况,请实现本方法,且加上这一个语句 124 setIntent(intent); 125 126 } 127 128 @Override 129 protected void onPause() { 130 // TODO Auto-generated method stub 131 super.onPause(); 132 133 SharedPreferences.Editor edtior = sp.edit(); 134 edtior.putString("SSP", "0"); 135 edtior.commit(); 136 } 137 138 @Override 139 public void onStop() { 140 super.onStop(); 141 PushManager.activityStoped(this); 142 // SharedPreferences.Editor edtior = sp.edit(); 143 // edtior.putString("Login", "-1"); 144 // edtior.commit(); 145 // } 146 } 147 148 @Override 149 protected void onDestroy() { 150 // TODO Auto-generated method stub 151 super.onDestroy(); 152 // SharedPreferences.Editor edtior = sp.edit(); 153 // edtior.putString("Login", "-1"); 154 // edtior.commit(); 155 } 156 157 @Override 158 public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { 159 // TODO Auto-generated method stub 160 161 } 162 163 public boolean onCreateOptionsMenu(Menu menu) { 164 // 调用父类方法来加入系统菜单 165 // 虽然目前android还没有系统菜单,但是为了兼容到以后的版本,最好加上 166 super.onCreateOptionsMenu(menu); 167 168 // 添加菜单项(多种方式) 169 // 1.直接指定标题 170 menu.add(1, 0, 1, "退出"); 171 172 // 3.显示指定菜单项的组号、ID、排序号、标题 173 174 // 如果希望显示菜单,请返回true 175 return true; 176 } 177 178 @Override 179 public boolean onOptionsItemSelected(MenuItem item) { 180 switch (item.getItemId()) { 181 // 响应每个菜单项(通过菜单项的ID) 182 183 case 0: 184 change(); 185 finish(); 186 // do something here 187 break; 188 default: 189 // 对没有处理的事件,交给父类来处理 190 return super.onOptionsItemSelected(item); 191 } 192 // 返回true表示处理完菜单项的事件,不需要将该事件继续传播下去了 193 return true; 194 } 195 196 197 //修改当前活动activity的状态 198 public void change() { 199 SharedPreferences.Editor edtior = sp.edit(); 200 edtior.putString("Login", "-1"); 201 edtior.commit(); 202 } 203 }
到这里,对话列表的界面搭建已经完成了,下一篇文章里面介绍聊天界面写法
基于百度云推送的实时通信客户端实现(二),布布扣,bubuko.com
原文:http://www.cnblogs.com/cwr941012/p/3585246.html