多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > 環信UI開源Demo情景分析十二、聊天界面(四)

環信UI開源Demo情景分析十二、聊天界面(四)

來源:程序員人生   發布時間:2015-05-04 09:49:11 閱讀次數:6243次

在這1章我們來分析1下聊天界面中消息的顯示,MessageAdapter。

public MessageAdapter(Context context, String username, int chatType) { this.username = username; this.context = context; inflater = LayoutInflater.from(context); activity = (Activity) context; this.conversation = EMChatManager.getInstance().getConversation(username); }

其中構造方法中是對成員變量的賦值。

并且在適配器里面還聲明了1個Handler:

Handler handler = new Handler() { private void refreshList() { // UI線程不能直接使用conversation.getAllMessages() // 否則在UI刷新進程中,如果收到新的消息,會致使并提問題 messages = (EMMessage[]) conversation.getAllMessages().toArray(new EMMessage[conversation.getAllMessages().size()]); for (int i = 0; i < messages.length; i++) { // getMessage will set message as read status conversation.getMessage(i); } notifyDataSetChanged(); } @Override public void handleMessage(android.os.Message message) { switch (message.what) { case HANDLER_MESSAGE_REFRESH_LIST: refreshList(); break; case HANDLER_MESSAGE_SELECT_LAST: if (activity instanceof ChatActivity) { ListView listView = ((ChatActivity) activity).getListView(); if (messages.length > 0) { listView.setSelection(messages.length - 1); } } break; case HANDLER_MESSAGE_SEEK_TO: int position = message.arg1; if (activity instanceof ChatActivity) { ListView listView = ((ChatActivity) activity).getListView(); listView.setSelection(position); } break; default: break; } } };

當傳遞過來的消息為HANDLER_MESSAGE_REFRESH_LIST時,調用refreshList方法刷新UI。當傳遞過來的消息為HANDLER_MESSAGE_SELECT_LAST時,將ListVIew轉動到最后1項。當傳遞過來的消息為HANDLER_MESSAGE_SEEK_TO時,將ListView轉動到指定位置。
/** * 獲得item數 */ public int getCount() { return messages == null ? 0 : messages.length; }

如果沒有消息返回0.
/** * 刷新頁面 */ public void refresh() { if (handler.hasMessages(HANDLER_MESSAGE_REFRESH_LIST)) { return; } android.os.Message msg = handler.obtainMessage(HANDLER_MESSAGE_REFRESH_LIST); handler.sendMessage(msg); }

如果Handler中沒有HANDLER_MESSAGE_REFRESH_LIST消息的時候發送此消息。
/** * 刷新頁面, 選擇最后1個 */ public void refreshSelectLast() { handler.sendMessage(handler.obtainMessage(HANDLER_MESSAGE_REFRESH_LIST)); handler.sendMessage(handler.obtainMessage(HANDLER_MESSAGE_SELECT_LAST)); }     /**      * 刷新頁面, 選擇Position      */     public void refreshSeekTo(int position) {         handler.sendMessage(handler.obtainMessage(HANDLER_MESSAGE_REFRESH_LIST));         android.os.Message msg = handler.obtainMessage(HANDLER_MESSAGE_SEEK_TO);         msg.arg1 = position;         handler.sendMessage(msg);     }
更改UI前先刷新UI。
public EMMessage getItem(int position) { if (messages != null && position < messages.length) { return messages[position]; } return null; } public long getItemId(int position) { return position; }
Adapter中需要重載的方法。
private static final int MESSAGE_TYPE_RECV_TXT = 0; private static final int MESSAGE_TYPE_SENT_TXT = 1; private static final int MESSAGE_TYPE_SENT_IMAGE = 2; private static final int MESSAGE_TYPE_SENT_LOCATION = 3; private static final int MESSAGE_TYPE_RECV_LOCATION = 4; private static final int MESSAGE_TYPE_RECV_IMAGE = 5; private static final int MESSAGE_TYPE_SENT_VOICE = 6; private static final int MESSAGE_TYPE_RECV_VOICE = 7; private static final int MESSAGE_TYPE_SENT_VIDEO = 8; private static final int MESSAGE_TYPE_RECV_VIDEO = 9; private static final int MESSAGE_TYPE_SENT_FILE = 10; private static final int MESSAGE_TYPE_RECV_FILE = 11; private static final int MESSAGE_TYPE_SENT_VOICE_CALL = 12; private static final int MESSAGE_TYPE_RECV_VOICE_CALL = 13; private static final int MESSAGE_TYPE_SENT_VIDEO_CALL = 14; private static final int MESSAGE_TYPE_RECV_VIDEO_CALL = 15;     /**      * 獲得item類型數      */     public int getViewTypeCount() {         return 16;     }
獲得消息類型的個數。
/** * 獲得item類型 */ public int getItemViewType(int position) { EMMessage message = getItem(position); if (message == null) { return ⑴; } if (message.getType() == EMMessage.Type.TXT) { if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false)) return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VOICE_CALL : MESSAGE_TYPE_SENT_VOICE_CALL; else if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, false)) return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VIDEO_CALL : MESSAGE_TYPE_SENT_VIDEO_CALL; return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_TXT : MESSAGE_TYPE_SENT_TXT; } if (message.getType() == EMMessage.Type.IMAGE) { return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_IMAGE : MESSAGE_TYPE_SENT_IMAGE; } if (message.getType() == EMMessage.Type.LOCATION) { return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_LOCATION : MESSAGE_TYPE_SENT_LOCATION; } if (message.getType() == EMMessage.Type.VOICE) { return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VOICE : MESSAGE_TYPE_SENT_VOICE; } if (message.getType() == EMMessage.Type.VIDEO) { return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VIDEO : MESSAGE_TYPE_SENT_VIDEO; } if (message.getType() == EMMessage.Type.FILE) { return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_FILE : MESSAGE_TYPE_SENT_FILE; } return ⑴;// invalid }
通過SDK來判斷具體是發送的消息還是接收的消息。
private View createViewByMessage(EMMessage message, int position) { switch (message.getType()) { case LOCATION: return message.direct == EMMessage.Direct.RECEIVE ? inflater.inflate(R.layout.row_received_location, null) : inflater.inflate(R.layout.row_sent_location, null); case IMAGE: return message.direct == EMMessage.Direct.RECEIVE ? inflater.inflate(R.layout.row_received_picture, null) : inflater.inflate(R.layout.row_sent_picture, null); case VOICE: return message.direct == EMMessage.Direct.RECEIVE ? inflater.inflate(R.layout.row_received_voice, null) : inflater.inflate(R.layout.row_sent_voice, null); case VIDEO: return message.direct == EMMessage.Direct.RECEIVE ? inflater.inflate(R.layout.row_received_video, null) : inflater.inflate(R.layout.row_sent_video, null); case FILE: return message.direct == EMMessage.Direct.RECEIVE ? inflater.inflate(R.layout.row_received_file, null) : inflater.inflate(R.layout.row_sent_file, null); default: // 語音通話 if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false)) return message.direct == EMMessage.Direct.RECEIVE ? inflater.inflate(R.layout.row_received_voice_call, null) : inflater.inflate(R.layout.row_sent_voice_call, null); // 視頻通話 else if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, false)) return message.direct == EMMessage.Direct.RECEIVE ? inflater.inflate(R.layout.row_received_video_call, null) : inflater.inflate(R.layout.row_sent_video_call, null); return message.direct == EMMessage.Direct.RECEIVE ? inflater.inflate(R.layout.row_received_message, null) : inflater.inflate(R.layout.row_sent_message, null); } }

根據不同的消息類型來創建不同的布局,由于消息內容多是文本、或是視頻等,而且多是發過來的,或是發送出去的。所以要有不同的布局文件。

接下來就是最主要的方法了getView:

public View getView(final int position, View convertView, ViewGroup parent) { // 獲得具體的消息對象 final EMMessage message = getItem(position); // 取得消息類型 ChatType chatType = message.getChatType(); // 生命1個holder final ViewHolder holder; if (convertView == null) { holder = new ViewHolder(); // 創建該消息的布局 convertView = createViewByMessage(message, position); if (message.getType() == EMMessage.Type.IMAGE) { try { // 消息為圖片格式 holder.iv = ((ImageView) convertView.findViewById(R.id.iv_sendPicture)); holder.iv_avatar = (ImageView) convertView.findViewById(R.id.iv_userhead); holder.tv = (TextView) convertView.findViewById(R.id.percentage); holder.pb = (ProgressBar) convertView.findViewById(R.id.progressBar); holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status); holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid); } catch (Exception e) { } } else if (message.getType() == EMMessage.Type.TXT) { try { // 消息為文本格式 holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending); holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status); holder.iv_avatar = (ImageView) convertView.findViewById(R.id.iv_userhead); // 這里是文字內容 holder.tv = (TextView) convertView.findViewById(R.id.tv_chatcontent); holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid); } catch (Exception e) { } // 語音通話及視頻通話 if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false) || message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, false)) { holder.iv = (ImageView) convertView.findViewById(R.id.iv_call_icon); holder.tv = (TextView) convertView.findViewById(R.id.tv_chatcontent); } } else if (message.getType() == EMMessage.Type.VOICE) { // 消息為聲音 try { holder.iv = ((ImageView) convertView.findViewById(R.id.iv_voice)); holder.iv_avatar = (ImageView) convertView.findViewById(R.id.iv_userhead); holder.tv = (TextView) convertView.findViewById(R.id.tv_length); holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending); holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status); holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid); holder.iv_read_status = (ImageView) convertView.findViewById(R.id.iv_unread_voice); } catch (Exception e) { } } else if (message.getType() == EMMessage.Type.LOCATION) { try { // 消息為地理位置 holder.iv_avatar = (ImageView) convertView.findViewById(R.id.iv_userhead); holder.tv = (TextView) convertView.findViewById(R.id.tv_location); holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending); holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status); holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid); } catch (Exception e) { } } else if (message.getType() == EMMessage.Type.VIDEO) { try { // 消息為視頻文件 holder.iv = ((ImageView) convertView.findViewById(R.id.chatting_content_iv)); holder.iv_avatar = (ImageView) convertView.findViewById(R.id.iv_userhead); holder.tv = (TextView) convertView.findViewById(R.id.percentage); holder.pb = (ProgressBar) convertView.findViewById(R.id.progressBar); holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status); holder.size = (TextView) convertView.findViewById(R.id.chatting_size_iv); holder.timeLength = (TextView) convertView.findViewById(R.id.chatting_length_iv); holder.playBtn = (ImageView) convertView.findViewById(R.id.chatting_status_btn); holder.container_status_btn = (LinearLayout) convertView.findViewById(R.id.container_status_btn); holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid); } catch (Exception e) { } } else if (message.getType() == EMMessage.Type.FILE) { try { // 消息為文件 holder.iv_avatar = (ImageView) convertView.findViewById(R.id.iv_userhead); holder.tv_file_name = (TextView) convertView.findViewById(R.id.tv_file_name); holder.tv_file_size = (TextView) convertView.findViewById(R.id.tv_file_size); holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending); holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status); holder.tv_file_download_state = (TextView) convertView.findViewById(R.id.tv_file_state); holder.ll_container = (LinearLayout) convertView.findViewById(R.id.ll_file_container); // 這里是進度值 holder.tv = (TextView) convertView.findViewById(R.id.percentage); } catch (Exception e) { } try { holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid); } catch (Exception e) { } } // 設置TAG convertView.setTag(holder); } else { // 獲得TAG holder = (ViewHolder) convertView.getTag(); } // 群聊時,顯示接收的消息的發送人的名稱 if (chatType == ChatType.GroupChat && message.direct == EMMessage.Direct.RECEIVE) { // demo里使用username代碼nick holder.tv_usernick.setText(message.getFrom()); } // 如果是發送的消息并且不是群聊消息,顯示已讀textview if (message.direct == EMMessage.Direct.SEND && chatType != ChatType.GroupChat) { holder.tv_ack = (TextView) convertView.findViewById(R.id.tv_ack); holder.tv_delivered = (TextView) convertView.findViewById(R.id.tv_delivered); if (holder.tv_ack != null) { if (message.isAcked) { if (holder.tv_delivered != null) { holder.tv_delivered.setVisibility(View.INVISIBLE); } holder.tv_ack.setVisibility(View.VISIBLE); } else { holder.tv_ack.setVisibility(View.INVISIBLE); // check and display msg delivered ack status if (holder.tv_delivered != null) { if (message.isDelivered) { holder.tv_delivered.setVisibility(View.VISIBLE); } else { holder.tv_delivered.setVisibility(View.INVISIBLE); } } } } } else { // 如果是文本或地圖消息并且不是group messgae,顯示的時候給對方發送已讀回執 if ((message.getType() == Type.TXT || message.getType() == Type.LOCATION) && !message.isAcked && chatType != ChatType.GroupChat) { // 不是語音通話記錄 if (!message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false)) { try { EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId()); // 發送已讀回執 message.isAcked = true; } catch (Exception e) { e.printStackTrace(); } } } } // 設置用戶頭像 setUserAvatar(message, holder.iv_avatar); switch (message.getType()) { // 根據消息type顯示item case IMAGE: // 圖片 handleImageMessage(message, holder, position, convertView); break; case TXT: // 文本 if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false) || message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, false)) // 音視頻通話 handleCallMessage(message, holder, position); else handleTextMessage(message, holder, position); break; case LOCATION: // 位置 handleLocationMessage(message, holder, position, convertView); break; case VOICE: // 語音 handleVoiceMessage(message, holder, position, convertView); break; case VIDEO: // 視頻 handleVideoMessage(message, holder, position, convertView); break; case FILE: // 1般文件 handleFileMessage(message, holder, position, convertView); break; default: // not supported } // 重發 if (message.direct == EMMessage.Direct.SEND) { View statusView = convertView.findViewById(R.id.msg_status); // 重發按鈕點擊事件 statusView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 顯示重發消息的自定義alertdialog Intent intent = new Intent(activity, AlertDialog.class); intent.putExtra("msg", activity.getString(R.string.confirm_resend)); intent.putExtra("title", activity.getString(R.string.resend)); intent.putExtra("cancel", true); intent.putExtra("position", position); if (message.getType() == EMMessage.Type.TXT) activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_TEXT); else if (message.getType() == EMMessage.Type.VOICE) activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_VOICE); else if (message.getType() == EMMessage.Type.IMAGE) activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_PICTURE); else if (message.getType() == EMMessage.Type.LOCATION) activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_LOCATION); else if (message.getType() == EMMessage.Type.FILE) activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_FILE); else if (message.getType() == EMMessage.Type.VIDEO) activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_VIDEO); } }); } else { final String st = context.getResources().getString(R.string.Into_the_blacklist); // 長按頭像,移入黑名單 holder.iv_avatar.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { Intent intent = new Intent(activity, AlertDialog.class); intent.putExtra("msg", st); intent.putExtra("cancel", true); intent.putExtra("position", position); activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_ADD_TO_BLACKLIST); return true; } }); } // 時間 TextView timestamp = (TextView) convertView.findViewById(R.id.timestamp); if (position == 0) { timestamp.setText(DateUtils.getTimestampString(new Date(message.getMsgTime()))); timestamp.setVisibility(View.VISIBLE); } else { // 兩條消息時間離得如果稍長,顯示時間 EMMessage prevMessage = getItem(position - 1); if (prevMessage != null && DateUtils.isCloseEnough(message.getMsgTime(), prevMessage.getMsgTime())) { timestamp.setVisibility(View.GONE); } else { timestamp.setText(DateUtils.getTimestampString(new Date(message.getMsgTime()))); timestamp.setVisibility(View.VISIBLE); } } return convertView; }
其中部份說明都已注釋。
/** * 顯示用戶頭像 * * @param message * @param imageView */ private void setUserAvatar(EMMessage message, ImageView imageView) { if (message.direct == Direct.SEND) { // 顯示自己頭像 UserUtils.setUserAvatar(context, EMChatManager.getInstance().getCurrentUser(), imageView); } else { UserUtils.setUserAvatar(context, message.getFrom(), imageView); } }
/** * 文本消息 * * @param message * @param holder * @param position */ private void handleTextMessage(EMMessage message, ViewHolder holder, final int position) { TextMessageBody txtBody = (TextMessageBody) message.getBody(); Spannable span = SmileUtils.getSmiledText(context, txtBody.getMessage()); // 設置內容 holder.tv.setText(span, BufferType.SPANNABLE); // 設置長按事件監聽 holder.tv.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { activity.startActivityForResult((new Intent(activity, ContextMenu.class)).putExtra("position", position).putExtra("type", EMMessage.Type.TXT.ordinal()), ChatActivity.REQUEST_CODE_CONTEXT_MENU); return true; } }); if (message.direct == EMMessage.Direct.SEND) { switch (message.status) { case SUCCESS: // 發送成功 holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.GONE); break; case FAIL: // 發送失敗 holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.VISIBLE); break; case INPROGRESS: // 發送中 holder.pb.setVisibility(View.VISIBLE); holder.staus_iv.setVisibility(View.GONE); break; default: // 發送消息 sendMsgInBackground(message, holder); } } }

其中對發送的文本消息進行狀態監聽。

/** * 音視頻通話記錄 * * @param message * @param holder * @param position */ private void handleCallMessage(EMMessage message, ViewHolder holder, final int position) { TextMessageBody txtBody = (TextMessageBody) message.getBody(); holder.tv.setText(txtBody.getMessage()); }

當音視頻通話的時候不能顯示音視頻,所以將文本信息顯示出來。

/**      * 圖片消息      *      * @param message      * @param holder      * @param position      * @param convertView      */     private void handleImageMessage(final EMMessage message, final ViewHolder holder, final int position, View convertView) {         //給當前圖片設置1個tag避免多張圖片躥亂         holder.pb.setTag(position);         holder.iv.setOnLongClickListener(new OnLongClickListener() {             @Override             public boolean onLongClick(View v) {                 //長按設置事件                 activity.startActivityForResult((new Intent(activity, ContextMenu.class)).putExtra("position", position).putExtra("type", EMMessage.Type.IMAGE.ordinal()), ChatActivity.REQUEST_CODE_CONTEXT_MENU);                 return true;             }         });         // 接收方向的消息         if (message.direct == EMMessage.Direct.RECEIVE) {             // "it is receive msg";             if (message.status == EMMessage.Status.INPROGRESS) {                 // "!!!! back receive";正在接收的時候顯示默許圖片                 holder.iv.setImageResource(R.drawable.default_image);                 //顯示下載進度條                 showDownloadImageProgress(message, holder);                 // downloadImage(message, holder);             } else {                 // "!!!! not back receive, show image directly");                 //發送圖片                 holder.pb.setVisibility(View.GONE);                 holder.tv.setVisibility(View.GONE);                 holder.iv.setImageResource(R.drawable.default_image);                 ImageMessageBody imgBody = (ImageMessageBody) message.getBody();                 if (imgBody.getLocalUrl() != null) {                     // String filePath = imgBody.getLocalUrl();                     String remotePath = imgBody.getRemoteUrl();                     String filePath = ImageUtils.getImagePath(remotePath);                     String thumbRemoteUrl = imgBody.getThumbnailUrl();                     String thumbnailPath = ImageUtils.getThumbnailImagePath(thumbRemoteUrl);                     //將圖片加載到Imageview里面                     showImageView(thumbnailPath, holder.iv, filePath, imgBody.getRemoteUrl(), message);                 }             }             return;         }         // 發送的消息         // process send message         // send pic, show the pic directly         ImageMessageBody imgBody = (ImageMessageBody) message.getBody();         String filePath = imgBody.getLocalUrl();         if (filePath != null && new File(filePath).exists()) {             showImageView(ImageUtils.getThumbnailImagePath(filePath), holder.iv, filePath, null, message);         } else {             showImageView(ImageUtils.getThumbnailImagePath(filePath), holder.iv, filePath, IMAGE_DIR, message);         }         switch (message.status) {         //圖片加載狀態         case SUCCESS:             holder.pb.setVisibility(View.GONE);             holder.tv.setVisibility(View.GONE);             holder.staus_iv.setVisibility(View.GONE);             break;         case FAIL:             holder.pb.setVisibility(View.GONE);             holder.tv.setVisibility(View.GONE);             holder.staus_iv.setVisibility(View.VISIBLE);             break;         case INPROGRESS:             holder.staus_iv.setVisibility(View.GONE);             holder.pb.setVisibility(View.VISIBLE);             holder.tv.setVisibility(View.VISIBLE);             if (timers.containsKey(message.getMsgId()))                 return;             // set a timer 設置1個定時器來顯示圖片的進度             final Timer timer = new Timer();             timers.put(message.getMsgId(), timer);             timer.schedule(new TimerTask() {                 @Override                 public void run() {                     activity.runOnUiThread(new Runnable() {                         public void run() {                             holder.pb.setVisibility(View.VISIBLE);                             holder.tv.setVisibility(View.VISIBLE);                             holder.tv.setText(message.progress + "%");                             if (message.status == EMMessage.Status.SUCCESS) {                                 holder.pb.setVisibility(View.GONE);                                 holder.tv.setVisibility(View.GONE);                                 // message.setSendingStatus(Message.SENDING_STATUS_SUCCESS);                                 timer.cancel();                             } else if (message.status == EMMessage.Status.FAIL) {                                 //發送失敗                                 holder.pb.setVisibility(View.GONE);                                 holder.tv.setVisibility(View.GONE);                                 // message.setSendingStatus(Message.SENDING_STATUS_FAIL);                                 // message.setProgress(0);                                 holder.staus_iv.setVisibility(View.VISIBLE);                                 Toast.makeText(activity, activity.getString(R.string.send_fail) + activity.getString(R.string.connect_failuer_toast), 0).show();                                 timer.cancel();                             }                         }                     });                 }             }, 0, 500);             break;         default:             sendPictureMessage(message, holder);         }     }

圖片消息。

/** * 視頻消息 * * @param message * @param holder * @param position * @param convertView */ private void handleVideoMessage(final EMMessage message, final ViewHolder holder, final int position, View convertView) { //獲得視頻對象 VideoMessageBody videoBody = (VideoMessageBody) message.getBody(); // final File image=new File(PathUtil.getInstance().getVideoPath(), // videoBody.getFileName()); String localThumb = videoBody.getLocalThumb(); holder.iv.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { //長按菜單 activity.startActivityForResult(new Intent(activity, ContextMenu.class).putExtra("position", position).putExtra("type", EMMessage.Type.VIDEO.ordinal()), ChatActivity.REQUEST_CODE_CONTEXT_MENU); return true; } }); if (localThumb != null) { //展現視頻縮略圖 showVideoThumbView(localThumb, holder.iv, videoBody.getThumbnailUrl(), message); } if (videoBody.getLength() > 0) { //設置視頻時長 String time = DateUtils.toTimeBySecond(videoBody.getLength()); holder.timeLength.setText(time); } //播放按鈕 holder.playBtn.setImageResource(R.drawable.video_download_btn_nor); if (message.direct == EMMessage.Direct.RECEIVE) { //接收到的視頻 if (videoBody.getVideoFileLength() > 0) { //視頻大小 String size = TextFormater.getDataSize(videoBody.getVideoFileLength()); holder.size.setText(size); } } else { //發送的視頻 if (videoBody.getLocalUrl() != null && new File(videoBody.getLocalUrl()).exists()) { String size = TextFormater.getDataSize(new File(videoBody.getLocalUrl()).length()); holder.size.setText(size); } } if (message.direct == EMMessage.Direct.RECEIVE) { // System.err.println("it is receive msg"); //顯示進度條 if (message.status == EMMessage.Status.INPROGRESS) { // System.err.println("!!!! back receive"); holder.iv.setImageResource(R.drawable.default_image); showDownloadImageProgress(message, holder); } else { // System.err.println("!!!! not back receive, show image directly"); holder.iv.setImageResource(R.drawable.default_image); if (localThumb != null) { showVideoThumbView(localThumb, holder.iv, videoBody.getThumbnailUrl(), message); } } return; } //對進度條設置tag holder.pb.setTag(position); // until here ,deal with send video msg //發送的結果 switch (message.status) { case SUCCESS: holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); break; case FAIL: holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.VISIBLE); break; case INPROGRESS: if (timers.containsKey(message.getMsgId())) return; // set a timer final Timer timer = new Timer(); timers.put(message.getMsgId(), timer); timer.schedule(new TimerTask() { @Override public void run() { //500毫秒更新1次 activity.runOnUiThread(new Runnable() { @Override public void run() { holder.pb.setVisibility(View.VISIBLE); holder.tv.setVisibility(View.VISIBLE); holder.tv.setText(message.progress + "%"); if (message.status == EMMessage.Status.SUCCESS) { holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); // message.setSendingStatus(Message.SENDING_STATUS_SUCCESS); timer.cancel(); } else if (message.status == EMMessage.Status.FAIL) { holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); // message.setSendingStatus(Message.SENDING_STATUS_FAIL); // message.setProgress(0); holder.staus_iv.setVisibility(View.VISIBLE); Toast.makeText(activity, activity.getString(R.string.send_fail) + activity.getString(R.string.connect_failuer_toast), 0).show(); timer.cancel(); } } }); } }, 0, 500); break; default: // sendMsgInBackground(message, holder); sendPictureMessage(message, holder); } }

視頻消息。
<span style="font-size:18px;"> /** * 語音消息 * * @param message * @param holder * @param position * @param convertView */ private void handleVoiceMessage(final EMMessage message, final ViewHolder holder, final int position, View convertView) { //語音對象 VoiceMessageBody voiceBody = (VoiceMessageBody) message.getBody(); holder.tv.setText(voiceBody.getLength() + """); //語音播放事件 holder.iv.setOnClickListener(new VoicePlayClickListener(message, holder.iv, holder.iv_read_status, this, activity, username)); holder.iv.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { //長按上下文菜單 activity.startActivityForResult((new Intent(activity, ContextMenu.class)).putExtra("position", position).putExtra("type", EMMessage.Type.VOICE.ordinal()), ChatActivity.REQUEST_CODE_CONTEXT_MENU); return true; } }); if (((ChatActivity) activity).playMsgId != null && ((ChatActivity) activity).playMsgId.equals(message.getMsgId()) && VoicePlayClickListener.isPlaying) { AnimationDrawable voiceAnimation; //顯示聲音播放動畫 if (message.direct == EMMessage.Direct.RECEIVE) { holder.iv.setImageResource(R.anim.voice_from_icon); } else { holder.iv.setImageResource(R.anim.voice_to_icon); } voiceAnimation = (AnimationDrawable) holder.iv.getDrawable(); voiceAnimation.start(); } else { //顯示為播放狀態下的界面 if (message.direct == EMMessage.Direct.RECEIVE) { holder.iv.setImageResource(R.drawable.chatfrom_voice_playing); } else { holder.iv.setImageResource(R.drawable.chatto_voice_playing); } } if (message.direct == EMMessage.Direct.RECEIVE) { if (message.isListened()) { // 隱藏語音未聽標志 holder.iv_read_status.setVisibility(View.INVISIBLE); } else { holder.iv_read_status.setVisibility(View.VISIBLE); } System.err.println("it is receive msg"); if (message.status == EMMessage.Status.INPROGRESS) { holder.pb.setVisibility(View.VISIBLE); System.err.println("!!!! back receive"); //監聽收到的語音文件消息完成下載 ((FileMessageBody) message.getBody()).setDownloadCallback(new EMCallBack() { @Override public void onSuccess() { activity.runOnUiThread(new Runnable() { @Override public void run() { //下載以后更新數據 holder.pb.setVisibility(View.INVISIBLE); notifyDataSetChanged(); } }); } @Override public void onProgress(int progress, String status) { } @Override public void onError(int code, String message) { activity.runOnUiThread(new Runnable() { @Override public void run() { //下載失敗,隱藏進度條 holder.pb.setVisibility(View.INVISIBLE); } }); } }); } else { //沒有進度的情況 holder.pb.setVisibility(View.INVISIBLE); } return; } // until here, deal with send voice msg //消息的結果 switch (message.status) { case SUCCESS: holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.GONE); break; case FAIL: holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.VISIBLE); break; case INPROGRESS: holder.pb.setVisibility(View.VISIBLE); holder.staus_iv.setVisibility(View.GONE); break; default: sendMsgInBackground(message, holder); } }</span>

語音消息。
/** * 文件消息 * * @param message * @param holder * @param position * @param convertView */ private void handleFileMessage(final EMMessage message, final ViewHolder holder, int position, View convertView) { final NormalFileMessageBody fileMessageBody = (NormalFileMessageBody) message.getBody(); final String filePath = fileMessageBody.getLocalUrl(); holder.tv_file_name.setText(fileMessageBody.getFileName()); holder.tv_file_size.setText(TextFormater.getDataSize(fileMessageBody.getFileSize())); holder.ll_container.setOnClickListener(new OnClickListener() { //文件點擊事件 @Override public void onClick(View view) { File file = new File(filePath); if (file != null && file.exists()) { // 文件存在,直接打開(SDK所提供的類) FileUtils.openFile(file, (Activity) context); } else { // 下載 context.startActivity(new Intent(context, ShowNormalFileActivity.class).putExtra("msgbody", fileMessageBody)); } if (message.direct == EMMessage.Direct.RECEIVE && !message.isAcked) { try { //文件確認 EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId()); message.isAcked = true; } catch (EaseMobException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); String st1 = context.getResources().getString(R.string.Have_downloaded); String st2 = context.getResources().getString(R.string.Did_not_download); if (message.direct == EMMessage.Direct.RECEIVE) { // 接收的消息 System.err.println("it is receive msg"); File file = new File(filePath); if (file != null && file.exists()) { holder.tv_file_download_state.setText(st1); } else { holder.tv_file_download_state.setText(st2); } return; } // until here, deal with send voice msg switch (message.status) { case SUCCESS: holder.pb.setVisibility(View.INVISIBLE); holder.tv.setVisibility(View.INVISIBLE); holder.staus_iv.setVisibility(View.INVISIBLE); break; case FAIL: holder.pb.setVisibility(View.INVISIBLE); holder.tv.setVisibility(View.INVISIBLE); holder.staus_iv.setVisibility(View.VISIBLE); break; case INPROGRESS: if (timers.containsKey(message.getMsgId())) return; // set a timer final Timer timer = new Timer(); timers.put(message.getMsgId(), timer); timer.schedule(new TimerTask() { @Override public void run() { activity.runOnUiThread(new Runnable() { //與語音消息1樣的處理 @Override public void run() { holder.pb.setVisibility(View.VISIBLE); holder.tv.setVisibility(View.VISIBLE); holder.tv.setText(message.progress + "%"); if (message.status == EMMessage.Status.SUCCESS) { holder.pb.setVisibility(View.INVISIBLE); holder.tv.setVisibility(View.INVISIBLE); timer.cancel(); } else if (message.status == EMMessage.Status.FAIL) { holder.pb.setVisibility(View.INVISIBLE); holder.tv.setVisibility(View.INVISIBLE); holder.staus_iv.setVisibility(View.VISIBLE); Toast.makeText(activity, activity.getString(R.string.send_fail) + activity.getString(R.string.connect_failuer_toast), 0).show(); timer.cancel(); } } }); } }, 0, 500); break; default: // 發送消息 sendMsgInBackground(message, holder); } }
文件消息。
/** * 處理位置消息 * * @param message * @param holder * @param position * @param convertView */ private void handleLocationMessage(final EMMessage message, final ViewHolder holder, final int position, View convertView) { //位置信息對象 TextView locationView = ((TextView) convertView.findViewById(R.id.tv_location)); LocationMessageBody locBody = (LocationMessageBody) message.getBody(); locationView.setText(locBody.getAddress()); //經緯度信息 LatLng loc = new LatLng(locBody.getLatitude(), locBody.getLongitude()); //地圖點擊事假 locationView.setOnClickListener(new MapClickListener(loc, locBody.getAddress())); locationView.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { //長按 上下文菜單 activity.startActivityForResult((new Intent(activity, ContextMenu.class)).putExtra("position", position).putExtra("type", EMMessage.Type.LOCATION.ordinal()), ChatActivity.REQUEST_CODE_CONTEXT_MENU); return false; } }); if (message.direct == EMMessage.Direct.RECEIVE) { return; } // deal with send message //消息發送狀態 switch (message.status) { case SUCCESS: holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.GONE); break; case FAIL: holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.VISIBLE); break; case INPROGRESS: holder.pb.setVisibility(View.VISIBLE); break; default: sendMsgInBackground(message, holder); } }

位置消息。

以上都為消息的邏輯處理,接下來是發送的處理。

/** * 發送消息 * * @param message * @param holder<pre name="code" class="java"> /* * 文件下載 * chat sdk will automatic download thumbnail image for the image message we * need to register callback show the download progress */ private void showDownloadImageProgress(final EMMessage message, final ViewHolder holder) { System.err.println("!!! show download image progress"); // final ImageMessageBody msgbody = (ImageMessageBody) // message.getBody(); final FileMessageBody msgbody = (FileMessageBody) message.getBody(); if (holder.pb != null) holder.pb.setVisibility(View.VISIBLE); if (holder.tv != null) holder.tv.setVisibility(View.VISIBLE); // 異步下載文件 msgbody.setDownloadCallback(new EMCallBack() { @Override public void onSuccess() { activity.runOnUiThread(new Runnable() { @Override public void run() { // message.setBackReceive(false); if (message.getType() == EMMessage.Type.IMAGE) { holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); } notifyDataSetChanged(); } }); } @Override public void onError(int code, String message) { } @Override public void onProgress(final int progress, String status) { if (message.getType() == EMMessage.Type.IMAGE) { activity.runOnUiThread(new Runnable() { //顯示下載進度 @Override public void run() { holder.tv.setText(progress + "%"); } }); } } }); }

* @param position */public void sendMsgInBackground(final EMMessage message, final ViewHolder holder) {holder.staus_iv.setVisibility(View.GONE);holder.pb.setVisibility(View.VISIBLE);final long start = System.currentTimeMillis();// 調用sdk發送異步發送方法EMChatManager.getInstance().sendMessage(message, new EMCallBack() {@Overridepublic void onSuccess() {//更新發送狀態updateSendedView(message, holder);}@Overridepublic void onError(int code, String error) {updateSendedView(message, holder);}@Overridepublic void onProgress(int progress, String status) {}});}


/* * 發送圖片 send message with new sdk */ private void sendPictureMessage(final EMMessage message, final ViewHolder holder) { try { // 獲得發送對象 String to = message.getTo(); // before send, update ui holder.staus_iv.setVisibility(View.GONE); holder.pb.setVisibility(View.VISIBLE); holder.tv.setVisibility(View.VISIBLE); holder.tv.setText("0%"); final long start = System.currentTimeMillis(); // if (chatType == ChatActivity.CHATTYPE_SINGLE) { EMChatManager.getInstance().sendMessage(message, new EMCallBack() { // 異步發送 @Override public void onSuccess() { Log.d(TAG, "send image message successfully"); activity.runOnUiThread(new Runnable() { public void run() { // send success holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); } }); } @Override public void onError(int code, String error) { activity.runOnUiThread(new Runnable() { public void run() { holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); // message.setSendingStatus(Message.SENDING_STATUS_FAIL); holder.staus_iv.setVisibility(View.VISIBLE); Toast.makeText(activity, activity.getString(R.string.send_fail) + activity.getString(R.string.connect_failuer_toast), 0).show(); } }); } @Override public void onProgress(final int progress, String status) { activity.runOnUiThread(new Runnable() { public void run() { holder.tv.setText(progress + "%"); } }); } }); } catch (Exception e) { e.printStackTrace(); } }

/** * 更新ui上消息發送狀態 * * @param message * @param holder */ private void updateSendedView(final EMMessage message, final ViewHolder holder) { activity.runOnUiThread(new Runnable() { @Override public void run() { // send success if (message.getType() == EMMessage.Type.VIDEO) { holder.tv.setVisibility(View.GONE); } System.out.println("message status : " + message.status); if (message.status == EMMessage.Status.SUCCESS) { // if (message.getType() == EMMessage.Type.FILE) { // holder.pb.setVisibility(View.INVISIBLE); // holder.staus_iv.setVisibility(View.INVISIBLE); // } else { // holder.pb.setVisibility(View.GONE); // holder.staus_iv.setVisibility(View.GONE); // } } else if (message.status == EMMessage.Status.FAIL) { // if (message.getType() == EMMessage.Type.FILE) { // holder.pb.setVisibility(View.INVISIBLE); // } else { // holder.pb.setVisibility(View.GONE); // } // holder.staus_iv.setVisibility(View.VISIBLE); Toast.makeText(activity, activity.getString(R.string.send_fail) + activity.getString(R.string.connect_failuer_toast), 0).show(); } notifyDataSetChanged(); } }); }

/** * load image into image view * 顯示圖片到控件中 * @param thumbernailPath * @param iv * @param position * @return the image exists or not */ private boolean showImageView(final String thumbernailPath, final ImageView iv, final String localFullSizePath, String remoteDir, final EMMessage message) { // String imagename = // localFullSizePath.substring(localFullSizePath.lastIndexOf("/") + 1, // localFullSizePath.length()); // final String remote = remoteDir != null ? remoteDir+imagename : // imagename; final String remote = remoteDir; EMLog.d("###", "local = " + localFullSizePath + " remote: " + remote); // first check if the thumbnail image already loaded into cache //獲得緩存文件 Bitmap bitmap = ImageCache.getInstance().get(thumbernailPath); if (bitmap != null) { //文件存在 // thumbnail image is already loaded, reuse the drawable iv.setImageBitmap(bitmap); iv.setClickable(true); iv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { System.err.println("image view on click"); //顯示大圖界面 Intent intent = new Intent(activity, ShowBigImage.class); File file = new File(localFullSizePath); if (file.exists()) { Uri uri = Uri.fromFile(file); intent.putExtra("uri", uri); System.err.println("here need to check why download everytime"); } else { // The local full size pic does not exist yet. // ShowBigImage needs to download it from the server // first // intent.putExtra("", message.get); ImageMessageBody body = (ImageMessageBody) message.getBody(); intent.putExtra("secret", body.getSecret()); intent.putExtra("remotepath", remote); } if (message != null && message.direct == EMMessage.Direct.RECEIVE && !message.isAcked && message.getChatType() != ChatType.GroupChat) { try { EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId()); message.isAcked = true; } catch (Exception e) { e.printStackTrace(); } } activity.startActivity(intent); } }); return true; } else { //文件不存在 重新加載 new LoadImageTask().execute(thumbernailPath, localFullSizePath, remote, message.getChatType(), iv, activity, message); return true; } }

/** * 展現視頻縮略圖 * * @param localThumb * 本地縮略圖路徑 * @param iv * @param thumbnailUrl * 遠程縮略圖路徑 * @param message */ private void showVideoThumbView(String localThumb, ImageView iv, String thumbnailUrl, final EMMessage message) { // first check if the thumbnail image already loaded into cache Bitmap bitmap = ImageCache.getInstance().get(localThumb); if (bitmap != null) { // thumbnail image is already loaded, reuse the drawable iv.setImageBitmap(bitmap); iv.setClickable(true); iv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { VideoMessageBody videoBody = (VideoMessageBody) message.getBody(); System.err.println("video view is on click"); Intent intent = new Intent(activity, ShowVideoActivity.class); intent.putExtra("localpath", videoBody.getLocalUrl()); intent.putExtra("secret", videoBody.getSecret()); intent.putExtra("remotepath", videoBody.getRemoteUrl()); if (message != null && message.direct == EMMessage.Direct.RECEIVE && !message.isAcked && message.getChatType() != ChatType.GroupChat) { message.isAcked = true; try { EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId()); } catch (Exception e) { e.printStackTrace(); } } activity.startActivity(intent); } }); } else { new LoadVideoImageTask().execute(localThumb, thumbnailUrl, iv, activity, message, this); } }

/* * 點擊地圖消息listener */ class MapClickListener implements View.OnClickListener { LatLng location; String address; public MapClickListener(LatLng loc, String address) { location = loc; this.address = address; } @Override public void onClick(View v) { Intent intent; //將聊天界面上的地圖用地圖界面顯示出來 intent = new Intent(context, BaiduMapActivity.class); intent.putExtra("latitude", location.latitude); intent.putExtra("longitude", location.longitude); intent.putExtra("address", address); activity.startActivity(intent); } }

至此,顯示聊天內容大體完成了,其中還有部份未詳講,顯示大圖界面,地圖界面。此處不在詳細說明。


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产精品成人亚洲 | 性欧美另类高清videos | 99久久999久久久综合精品涩 | 国产午夜精品久久久久九九 | 中文字幕无线码一区二区三区 | 国产一区二区在线视频观看 | 免费成年人视频在线观看 | 国产成人毛片精品不卡在线 | 国产成人精品综合久久久 | 性欧美精品| 视频在线视频免费观看 | 无人区一区二区三区乱码 | 毛片毛片毛片毛片出来毛片 | 久久国产精品视频 | 日本xxwwwxxxx18 | 欧美高清乌克兰精品另类 | 三级黄在线观看 | 男人激烈吃奶好舒服 | 中文字幕视频免费在线观看 | www.亚洲色图 | 免费一级欧美毛片 | 午夜视频在线观看免费视频 | 欧美性猛交xxxx免费看久久久 | 国产欧美日韩精品一区二区三区 | 激情文学激情图片 | 欧美丝袜高跟鞋一区二区 | 成人中文字幕在线 | 在线观看欧美亚洲 | 久久精品第一页 | 亚洲精品性夜夜夜 | 欧美人与禽xoxo性伦交 | 一二三四在线手机观看视频 | 国产精品亚洲精品日韩动图 | 亚洲线精品一区二区三区 | 国内久久久久影院精品 | 亚洲精品人成在线观看 | 欧美一区二区三区男人的天堂 | 国产一区二区三区欧美精品 | 性欧美一级 | 久久精品一级 | 欧美日韩看片 |