package com.wyp.materialqqlite.ui; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.os.AsyncTask; import android.os.Bundle; import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextClock; import android.widget.TextView; import java.io.File; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.Locale; import com.wyp.materialqqlite.AppData; import com.wyp.materialqqlite.FaceInfo; import com.wyp.materialqqlite.FaceList; import com.wyp.materialqqlite.ImageCache; import com.wyp.materialqqlite.R; import com.wyp.materialqqlite.Utils; import com.wyp.materialqqlite.qqclient.QQClient; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.BuddyInfo; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.BuddyList; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.Content; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.ContentType; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.GroupInfo; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.GroupList; public class ChatMsgAdapter extends BaseAdapter implements OnClickListener { private Context m_Context; private int m_nGroupCode; private List<ChatMsg> m_lnkChatMsg; private QQClient m_QQClient; private FaceList m_faceList; private ImageCache m_imgCache; private String m_strChatPicPath; private int m_cxAvatar, m_cyAvatar; private int m_pxAvatarRound; private int m_cxFace, m_cyFace; private int m_cxCFace, m_cyCFace; private int m_roundPx_L, m_roundPx_S; public ChatMsgAdapter(Context context, int nGroupCode, List<ChatMsg> lnkChatMsg) { m_Context = context; m_nGroupCode = nGroupCode; m_lnkChatMsg = lnkChatMsg; m_QQClient = AppData.getAppData().getQQClient(); m_faceList = AppData.getAppData().getFaceList(); m_imgCache = new ImageCache(); m_strChatPicPath = m_QQClient.getChatPicFolder(0); m_cxAvatar = (int)context. getResources().getDimension(R.dimen.chat_cxAvatar); m_cyAvatar = (int)context. getResources().getDimension(R.dimen.chat_cyAvatar); m_pxAvatarRound = (int)context. getResources().getDimension(R.dimen.pxAvatarRound); m_cxFace = (int)context. getResources().getDimension(R.dimen.cxFace); m_cyFace = (int)context. getResources().getDimension(R.dimen.cyFace); m_cxCFace = (int)context. getResources().getDimension(R.dimen.cxCFace); m_cyCFace = (int)context. getResources().getDimension(R.dimen.cyCFace); m_roundPx_L = (int)context. getResources().getDimension(R.dimen.chatPic_RoundPx_L); m_roundPx_S = (int)context. getResources().getDimension(R.dimen.chatPic_RoundPx_S); } public int getCount() { if (m_lnkChatMsg != null) return m_lnkChatMsg.size(); else return 0; } public Object getItem(int position) { if (m_lnkChatMsg != null) return m_lnkChatMsg.get(position); else return null; } public long getItemId(int position) { return position; } public int getItemViewType(int position) { if (m_lnkChatMsg != null) { ChatMsg chatMsg = m_lnkChatMsg.get(position); if (chatMsg != null) return chatMsg.m_nType; } return 0; } public int getViewTypeCount() { return ChatMsg.TYPE_COUNT; } public View getView(int position, View convertView, ViewGroup parent) { ChatMsg chatMsg = m_lnkChatMsg.get(position); if (null == chatMsg) return convertView; ViewHolder holder = null; if (null == convertView) { if (ChatMsg.LEFT_B == chatMsg.m_nType) { convertView = LayoutInflater.from(m_Context).inflate( R.layout.chat_listitem_left_b, parent, false); } else if (ChatMsg.LEFT_G == chatMsg.m_nType) { convertView = LayoutInflater.from(m_Context).inflate( R.layout.chat_listitem_left_g, parent, false); } else if (ChatMsg.RIGHT == chatMsg.m_nType) { convertView = LayoutInflater.from(m_Context).inflate( R.layout.chat_listitem_right, parent, false); } else if (ChatMsg.TIME == chatMsg.m_nType) { convertView = LayoutInflater.from(m_Context).inflate( R.layout.chat_listitem_time, parent, false); } if (convertView != null) { holder = new ViewHolder(); holder.m_imgAvatar = (ImageView)convertView .findViewById(R.id.chatlistitem_imgAvatar); holder.m_txtName = (TextView)convertView .findViewById(R.id.chatlistitem_txtName); holder.m_txtContent = (TextView)convertView .findViewById(R.id.chatlistitem_txtContent); holder.m_txtTime = (TextView)convertView .findViewById(R.id.chatlistitem_txtTime); if (holder.m_txtContent != null) { holder.m_txtContent.setHighlightColor(Color.TRANSPARENT); // android:textColorLink // android:textColorHighlight } convertView.setTag(holder); } } else { holder = (ViewHolder)convertView.getTag(); } if (null == holder) return convertView; if (ChatMsg.LEFT_B == chatMsg.m_nType) { Bitmap bmp; if (m_nGroupCode != 0) bmp = getSessHeadPic(m_nGroupCode, chatMsg.m_nQQUin); else bmp = getBuddyHeadPic(chatMsg.m_nQQUin); if (bmp != null) holder.m_imgAvatar.setImageBitmap(bmp); else holder.m_imgAvatar.setImageResource(R.drawable.h001); setBubble(holder.m_txtContent, chatMsg); SpannableStringBuilder strContent = getSpanStrBuilder(m_Context, chatMsg.m_arrContent); holder.m_txtContent.setText(strContent); } else if (ChatMsg.LEFT_G == chatMsg.m_nType) { Bitmap bmp = getSessHeadPic(m_nGroupCode, chatMsg.m_nQQUin); if (bmp != null) holder.m_imgAvatar.setImageBitmap(bmp); else holder.m_imgAvatar.setImageResource(R.drawable.h001); holder.m_imgAvatar.setTag(position); holder.m_imgAvatar.setOnClickListener(this); setBubble(holder.m_txtContent, chatMsg); holder.m_txtName.setText(chatMsg.m_strName + ":"); SpannableStringBuilder strContent = getSpanStrBuilder(m_Context, chatMsg.m_arrContent); holder.m_txtContent.setMovementMethod(LinkMovementMethod.getInstance()); holder.m_txtContent.setText(strContent); } else if (ChatMsg.RIGHT == chatMsg.m_nType) { Bitmap bmp = getBuddyHeadPic(chatMsg.m_nQQUin); if (bmp != null) holder.m_imgAvatar.setImageBitmap(bmp); else holder.m_imgAvatar.setImageResource(R.drawable.h001); setBubble(holder.m_txtContent, chatMsg); SpannableStringBuilder strContent = getSpanStrBuilder(m_Context, chatMsg.m_arrContent); holder.m_txtContent.setText(strContent); } else if (ChatMsg.TIME == chatMsg.m_nType) { String strTime = formatTime(chatMsg.m_nTime); holder.m_txtTime.setText(strTime); } return convertView; } private String formatTime(int nTime) { Calendar time = Calendar.getInstance(); time.setTimeInMillis(Utils.getUInt(nTime)*1000); if (Utils.isToday(nTime)) { // 今天 SimpleDateFormat dateFmt = new SimpleDateFormat("H:mm", Locale.getDefault()); return dateFmt.format(time.getTime()); } else if (Utils.isYesterday(nTime)) { // 昨天 SimpleDateFormat dateFmt = new SimpleDateFormat("昨天 H:mm", Locale.getDefault()); return dateFmt.format(time.getTime()); } else if (Utils.isThisYear(nTime)) { // 今年 SimpleDateFormat dateFmt = new SimpleDateFormat("MM-dd H:mm", Locale.getDefault()); return dateFmt.format(time.getTime()); } else { SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd H:mm", Locale.getDefault()); return dateFmt.format(time.getTime()); } } private SpannableStringBuilder getSpanStrBuilder( Context context, List<Content> arrContent) { if (null == context || null == arrContent) return null; SpannableStringBuilder spanStrBuilder = new SpannableStringBuilder(); for (int i = 0; i < arrContent.size(); i++) { Content content = arrContent.get(i); if (null == content) continue; if (content.m_nType == ContentType.CONTENT_TYPE_TEXT) { // 文字 spanStrBuilder.append(content.m_strText); } else if (content.m_nType == ContentType.CONTENT_TYPE_FACE) { // 表情 FaceInfo faceInfo = m_faceList.getFaceInfoById(content.m_nFaceId); SpannableString spanStr = Utils.getSysFace( m_Context, faceInfo, m_cxFace, m_cyFace); if (spanStr != null) spanStrBuilder.append(spanStr); } else if (content.m_nType == ContentType.CONTENT_TYPE_CUSTOM_FACE) { // 图片 if (spanStrBuilder.length() > 0) spanStrBuilder.append("\n"); String strFileName = m_strChatPicPath + content.m_CFaceInfo.m_strName; Bitmap bmp = m_imgCache.get(content.m_CFaceInfo.m_strName); if (null == bmp) { File file = new File(strFileName); if (!file.exists()) { } else { LoadImageTask task = new LoadImageTask(); task.m_strKey = content.m_CFaceInfo.m_strName; task.m_strFileName = strFileName; task.m_bIsHeadPic = false; task.execute(""); } SpannableString spanStr = Utils.getCustomFace( m_Context, R.drawable.aio_image_default_round, content.m_CFaceInfo.m_strName); if (spanStr != null) spanStrBuilder.append(spanStr); } else { ClickableSpan clickSpan = new ImageClickSpan(content.m_CFaceInfo.m_strName); SpannableString spanStr = Utils.getCustomFace( m_Context, bmp, content.m_CFaceInfo.m_strName, clickSpan); if (spanStr != null) spanStrBuilder.append(spanStr); } if (i != arrContent.size()-1) spanStrBuilder.append("\n"); } } return spanStrBuilder; } private Bitmap getBuddyHeadPic(int nQQUin) { if (0 == nQQUin) return null; BuddyInfo buddyInfo; if (nQQUin == m_QQClient.getUserInfo().m_nQQUin) { buddyInfo = m_QQClient.getUserInfo(); } else { BuddyList buddyList = m_QQClient.getBuddyList(); buddyInfo = buddyList.getBuddy(nQQUin); } if (null == buddyInfo) { return null; } if (0 == buddyInfo.m_nQQNum) { // 没有号码先更新号码 m_QQClient.updateBuddyNum(buddyInfo.m_nQQUin); return null; } Bitmap bmp = m_imgCache.get(buddyInfo.m_nQQNum); if (bmp != null) { return bmp; } String strFileName = m_QQClient.getBuddyHeadPicFullName(buddyInfo.m_nQQNum); File file = new File(strFileName); if (!file.exists()) { m_QQClient.updateBuddyHeadPic(buddyInfo.m_nQQUin, buddyInfo.m_nQQNum); return null; } LoadImageTask task = new LoadImageTask(); task.m_strKey = String.valueOf(buddyInfo.m_nQQNum); task.m_strFileName = strFileName; task.m_bIsHeadPic = true; task.execute(""); return null; } private Bitmap getSessHeadPic(int nGroupCode, int nQQUin) { if (0 == nGroupCode || 0 == nQQUin) return null; GroupList groupList = m_QQClient.getGroupList(); BuddyInfo buddyInfo = groupList.getGroupMemberByCode(nGroupCode, nQQUin); if (null == buddyInfo) { return null; } if (0 == buddyInfo.m_nQQNum) { m_QQClient.updateGroupMemberNum(nGroupCode, nQQUin); return null; } Bitmap bmp = m_imgCache.get(buddyInfo.m_nQQNum); if (bmp != null) { return bmp; } String strFileName = m_QQClient.getSessHeadPicFullName(buddyInfo.m_nQQNum); File file = new File(strFileName); if (!file.exists()) { m_QQClient.updateGroupMemberHeadPic(nGroupCode, nQQUin, buddyInfo.m_nQQNum); return null; } LoadImageTask task = new LoadImageTask(); task.m_strKey = String.valueOf(buddyInfo.m_nQQNum); task.m_strFileName = strFileName; task.m_bIsHeadPic = true; task.execute(""); return null; } private void setBubble(TextView txtContent, ChatMsg chatMsg) { Integer nOldBubble = (Integer)txtContent.getTag(); if (null == nOldBubble || nOldBubble != chatMsg.m_nBubble) { int left = txtContent.getPaddingLeft(); int right = txtContent.getPaddingRight(); int top = txtContent.getPaddingTop(); int bottom = txtContent.getPaddingBottom(); boolean bIsUser = (ChatMsg.RIGHT == chatMsg.m_nType); boolean bUseDefBubble = true; if (chatMsg.m_nBubble != 0) { // } if (bUseDefBubble) { if (bIsUser) { txtContent.setBackgroundResource(R.drawable.btn_style7); txtContent.setTextColor(0xFFFFFFFF); txtContent.setTextIsSelectable(true); txtContent.setLinkTextColor(0xFF0000FF); } else { txtContent.setBackgroundResource(R.drawable.btn_style6); txtContent.setTextColor(0xFF000000); txtContent.setTextIsSelectable(true); txtContent.setLinkTextColor(0xFF0000FF); } txtContent.setTag(0); } txtContent.setPadding(left, top, right, bottom); } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.chatlistitem_imgAvatar: int nPos = (Integer)v.getTag(); ChatMsg chatMsg = m_lnkChatMsg.get(nPos); if (chatMsg != null && m_nGroupCode != 0 && chatMsg.m_nQQUin != 0) { if (chatMsg.m_nType == ChatMsg.LEFT_G) { Intent intent = new Intent(m_Context, ChatActivity.class); Bundle bundle = new Bundle(); bundle.putInt("type", ChatActivity.IS_SESS); bundle.putInt("useruin", m_QQClient.getUserInfo().m_nQQUin); bundle.putString("username", m_QQClient.getUserInfo().m_strNickName); bundle.putInt("groupcode", m_nGroupCode); bundle.putInt("qquin", chatMsg.m_nQQUin); GroupList groupList = m_QQClient.getGroupList(); GroupInfo groupInfo = groupList.getGroupByCode(m_nGroupCode); if (groupInfo != null) { bundle.putInt("groupid", groupInfo.m_nGroupId); bundle.putInt("groupnum", groupInfo.m_nGroupNumber); bundle.putString("groupname", groupInfo.m_strName); BuddyInfo buddyInfo = groupInfo.getMemberByUin(chatMsg.m_nQQUin); if (buddyInfo != null) { bundle.putInt("qqnum", buddyInfo.m_nQQNum); if (!Utils.isEmptyStr(buddyInfo.m_strGroupCard)) bundle.putString("buddyname", buddyInfo.m_strGroupCard); else bundle.putString("buddyname", buddyInfo.m_strNickName); } else { bundle.putInt("qqnum", 0); bundle.putString("buddyname", ""); } } else { bundle.putInt("groupid", 0); bundle.putInt("groupnum", 0); bundle.putString("groupname", ""); bundle.putInt("qqnum", 0); bundle.putString("buddyname", ""); } intent.putExtras(bundle); m_Context.startActivity(intent); } } break; } } class ViewHolder { public ImageView m_imgAvatar; public TextView m_txtName; public TextView m_txtContent; public TextView m_txtTime; } private class ImageClickSpan extends ClickableSpan implements OnClickListener { private String m_strUrl; public ImageClickSpan(String strUrl) { super(); m_strUrl = strUrl; } @Override public void onClick(View v) { int nCurIndex = 0; ArrayList<String> arrUrl = new ArrayList<String>(); for (int i = 0; i < m_lnkChatMsg.size(); i++) { ChatMsg chatMsg = m_lnkChatMsg.get(i); if (null == chatMsg || null == chatMsg.m_arrContent) continue; for (int j = 0; j < chatMsg.m_arrContent.size(); j++) { Content content = chatMsg.m_arrContent.get(j); if (null == content) continue; if (ContentType.CONTENT_TYPE_CUSTOM_FACE == content.m_nType) { arrUrl.add(content.m_CFaceInfo.m_strName); if (m_strUrl.equals(content.m_CFaceInfo.m_strName)) nCurIndex = arrUrl.size()-1; } } } Intent intent = new Intent(m_Context, PicViewerActivity.class); intent.putStringArrayListExtra("urls", arrUrl); intent.putExtra("curindex", nCurIndex); m_Context.startActivity(intent); } } private class LoadImageTask extends AsyncTask<String, Integer, Boolean> { public String m_strKey = ""; public String m_strFileName = ""; public boolean m_bIsHeadPic = false; public Bitmap m_Bitmap = null; @Override protected Boolean doInBackground(String... params) { if (m_bIsHeadPic) { File file = new File(m_strFileName); int nTime = (int)(file.lastModified() / 1000); if (!Utils.isToday(nTime)) { file.delete(); return true; } m_Bitmap = BitmapFactory.decodeFile(m_strFileName); if (m_Bitmap != null) { m_Bitmap = Utils.zoomImg(m_Bitmap, m_cxAvatar, m_cyAvatar); m_Bitmap = Utils.getRoundedCornerBitmap(m_Bitmap, m_pxAvatarRound); } return m_Bitmap != null; } else { m_Bitmap = BitmapFactory.decodeFile(m_strFileName); if (m_Bitmap != null) { int cx = m_cxCFace; int cy = m_cyCFace; int cxBmp = m_Bitmap.getWidth(); int cyBmp = m_Bitmap.getHeight(); int roundPx; if (cxBmp > cx || cyBmp > cy) { if (cxBmp < cx) cx = cxBmp; if (cyBmp < cy) cy = cyBmp; m_Bitmap = Utils.zoomImg(m_Bitmap, cx, cy); roundPx = m_roundPx_L; } else { roundPx = m_roundPx_S; } m_Bitmap = Utils.getRoundedCornerBitmap(m_Bitmap, roundPx); } return m_Bitmap != null; } } @Override protected void onPostExecute(Boolean result) { if (result) { m_imgCache.put(m_strKey, m_Bitmap); ChatMsgAdapter.this.notifyDataSetChanged(); } } } }