@Override public int getItemViewType(int position) { Message msg = mMsgList.get(position); // 是文字类型或者自定义类型(用来显示群成员变化消息) if (msg.getContentType() == ContentType.text) { return msg.getDirect() == MessageDirect.send ? TYPE_SEND_TXT : TYPE_RECEIVE_TXT; } else if (msg.getContentType() == ContentType.image) { return msg.getDirect() == MessageDirect.send ? TYPE_SEND_IMAGE : TYPE_RECEIVER_IMAGE; } else if (msg.getContentType() == ContentType.voice) { return msg.getDirect() == MessageDirect.send ? TYPE_SEND_VOICE : TYPE_RECEIVER_VOICE; } else { return TYPE_CUSTOM_TXT; } }
@Override public View getView(int position, View convertView, ViewGroup parent) { Message msg = mMsgList.get(position); ViewHolder holder = new ViewHolder(); convertView = createViewByType(msg, position); if (msg.getDirect().equals(MessageDirect.send)) { holder.sendTime = (TextView) convertView.findViewById(R.id.send_time_txt); holder.sendAvatar = (CircleImageView) convertView.findViewById(R.id.send_avatar_iv); holder.sendFail = (ImageButton) convertView.findViewById(R.id.send_fail_resend_ib); holder.sendMsg = (TextView) convertView.findViewById(R.id.send_msg_content); holder.sendSending = (ImageView) convertView.findViewById(R.id.send_sending_iv); } else if (msg.getDirect().equals(MessageDirect.receive)) { holder.receiveTime = (TextView) convertView.findViewById(R.id.receive_time_txt); holder.receiveAvatar = (CircleImageView) convertView.findViewById(R.id.receive_avatar_iv); holder.receiveMsg = (TextView) convertView.findViewById(R.id.receive_msg_content); } if (msg.getDirect().equals(MessageDirect.receive)) { showTime(holder.receiveTime, msg, position); showAvatar(holder.receiveAvatar, msg); String content = ((TextContent) msg.getContent()).getText(); holder.receiveMsg.setText(content); } if (msg.getDirect().equals(MessageDirect.send)) { showTime(holder.sendTime, msg, position); String userID = PrefUtils.getString(context, "loginUser", null); User user = new DatabaseUtils(context).queryUser(userID); ImageUtils.bindImageWithOptions( holder.sendAvatar, user.user_avatar, R.drawable.person_avatar_default_round, R.drawable.person_avatar_default_round); String content = ((TextContent) msg.getContent()).getText(); holder.sendMsg.setText(content); handleTextMsg(msg, holder); } return convertView; }
private void handleTextMsg( final Message msg, final ViewHolder holder, OnLongClickListener longClickListener) { final String content = ((TextContent) msg.getContent()).getText(); holder.txtContent.setText(content); holder.txtContent.setOnLongClickListener(longClickListener); // 检查发送状态,发送方有重发机制 if (msg.getDirect() == MessageDirect.send) { final Animation sendingAnim = AnimationUtils.loadAnimation(mContext, R.anim.jmui_rotate); LinearInterpolator lin = new LinearInterpolator(); sendingAnim.setInterpolator(lin); switch (msg.getStatus()) { case send_success: holder.sendingIv.clearAnimation(); holder.sendingIv.setVisibility(View.GONE); holder.resend.setVisibility(View.GONE); break; case send_fail: holder.sendingIv.clearAnimation(); holder.sendingIv.setVisibility(View.GONE); holder.resend.setVisibility(View.VISIBLE); break; case send_going: sendingTextOrVoice(holder, sendingAnim, msg); break; default: } // 点击重发按钮,重发消息 holder.resend.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { showResendDialog(holder, sendingAnim, msg); } }); } else { if (mIsGroup) { holder.displayName.setVisibility(View.VISIBLE); if (TextUtils.isEmpty(msg.getFromUser().getNickname())) { holder.displayName.setText(msg.getFromUser().getUserName()); } else { holder.displayName.setText(msg.getFromUser().getNickname()); } } } }
private void handleVoiceMsg( final Message msg, final ViewHolder holder, final int position, OnLongClickListener longClickListener) { final VoiceContent content = (VoiceContent) msg.getContent(); final MessageDirect msgDirect = msg.getDirect(); int length = content.getDuration(); String voiceLength = length + mContext.getString(R.string.symbol_second); holder.voiceLength.setText(voiceLength); // 控制语音长度显示,长度增幅随语音长度逐渐缩小 int width = (int) (-0.04 * length * length + 4.526 * length + 75.214); holder.txtContent.setWidth((int) (width * mDensity)); holder.txtContent.setOnLongClickListener(longClickListener); if (msgDirect == MessageDirect.send) { holder.voice.setImageResource(R.drawable.jmui_send_3); final Animation sendingAnim = AnimationUtils.loadAnimation(mContext, R.anim.jmui_rotate); LinearInterpolator lin = new LinearInterpolator(); sendingAnim.setInterpolator(lin); switch (msg.getStatus()) { case send_success: holder.sendingIv.clearAnimation(); holder.sendingIv.setVisibility(View.GONE); holder.resend.setVisibility(View.GONE); break; case send_fail: holder.sendingIv.clearAnimation(); holder.sendingIv.setVisibility(View.GONE); holder.resend.setVisibility(View.VISIBLE); break; case send_going: sendingTextOrVoice(holder, sendingAnim, msg); break; default: } holder.resend.setOnClickListener( new OnClickListener() { @Override public void onClick(View arg0) { if (msg.getContent() != null) { showResendDialog(holder, sendingAnim, msg); } else { Toast.makeText( mContext, mContext.getString(R.string.sdcard_not_exist_toast), Toast.LENGTH_SHORT) .show(); } } }); } else switch (msg.getStatus()) { case receive_success: if (mIsGroup) { holder.displayName.setVisibility(View.VISIBLE); if (TextUtils.isEmpty(msg.getFromUser().getNickname())) { holder.displayName.setText(msg.getFromUser().getUserName()); } else { holder.displayName.setText(msg.getFromUser().getNickname()); } } holder.voice.setImageResource(R.drawable.jmui_receive_3); // 收到语音,设置未读 if (msg.getContent().getBooleanExtra("isReaded") == null || !msg.getContent().getBooleanExtra("isReaded")) { mConv.updateMessageExtra(msg, "isReaded", false); holder.readStatus.setVisibility(View.VISIBLE); if (mIndexList.size() > 0) { if (!mIndexList.contains(position)) { addTolistAndSort(position); } } else { addTolistAndSort(position); } if (nextPlayPosition == position && autoPlay) { playVoice(position, holder, false); } } else if (msg.getContent().getBooleanExtra("isReaded").equals(true)) { holder.readStatus.setVisibility(View.GONE); } break; case receive_fail: holder.voice.setImageResource(R.drawable.jmui_receive_3); // 接收失败,从服务器上下载 content.downloadVoiceFile( msg, new DownloadCompletionCallback() { @Override public void onComplete(int status, String desc, File file) { if (status != 0) { Toast.makeText( mContext, mContext.getString(R.string.voice_fetch_failed_toast), Toast.LENGTH_SHORT) .show(); } else { Log.i("VoiceMessage", "reload success"); } } }); break; case receive_going: break; default: } holder.txtContent.setOnClickListener( new OnClickListener() { @Override public void onClick(View arg0) { if (!FileHelper.isSdCardExist() && msg.getDirect() == MessageDirect.send) { Toast.makeText( mContext, mContext.getString(R.string.sdcard_not_exist_toast), Toast.LENGTH_SHORT) .show(); return; } // 如果之前存在播放动画,无论这次点击触发的是暂停还是播放,停止上次播放的动画 if (mVoiceAnimation != null) { mVoiceAnimation.stop(); } // 播放中点击了正在播放的Item 则暂停播放 if (mp.isPlaying() && mPosition == position) { if (msgDirect == MessageDirect.send) { holder.voice.setImageResource(R.anim.jmui_voice_send); } else { holder.voice.setImageResource(R.anim.jmui_voice_receive); } mVoiceAnimation = (AnimationDrawable) holder.voice.getDrawable(); pauseVoice(); mVoiceAnimation.stop(); // 开始播放录音 } else if (msgDirect == MessageDirect.send) { holder.voice.setImageResource(R.anim.jmui_voice_send); mVoiceAnimation = (AnimationDrawable) holder.voice.getDrawable(); // 继续播放之前暂停的录音 if (mSetData && mPosition == position) { mVoiceAnimation.start(); mp.start(); // 否则重新播放该录音或者其他录音 } else { playVoice(position, holder, true); } // 语音接收方特殊处理,自动连续播放未读语音 } else { try { // 继续播放之前暂停的录音 if (mSetData && mPosition == position) { if (mVoiceAnimation != null) { mVoiceAnimation.start(); } mp.start(); // 否则开始播放另一条录音 } else { // 选中的录音是否已经播放过,如果未播放,自动连续播放这条语音之后未播放的语音 if (msg.getContent().getBooleanExtra("isReaded") == null || !msg.getContent().getBooleanExtra("isReaded")) { autoPlay = true; playVoice(position, holder, false); // 否则直接播放选中的语音 } else { holder.voice.setImageResource(R.anim.jmui_voice_receive); mVoiceAnimation = (AnimationDrawable) holder.voice.getDrawable(); playVoice(position, holder, false); } } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } } } }); }
// 处理图片 private void handleImgMsg(final Message msg, final ViewHolder holder, final int position) { final ImageContent imgContent = (ImageContent) msg.getContent(); // 先拿本地缩略图 final String path = imgContent.getLocalThumbnailPath(); // 接收图片 if (msg.getDirect() == MessageDirect.receive) { if (path == null) { // 从服务器上拿缩略图 imgContent.downloadThumbnailImage( msg, new DownloadCompletionCallback() { @Override public void onComplete(int status, String desc, File file) { if (status == 0) { Picasso.with(mContext).load(file).into(holder.picture); } } }); } else { setPictureScale(path, holder.picture); Picasso.with(mContext).load(new File(path)).into(holder.picture); } // 群聊中显示昵称 if (mIsGroup) { holder.displayName.setVisibility(View.VISIBLE); if (TextUtils.isEmpty(msg.getFromUser().getNickname())) { holder.displayName.setText(msg.getFromUser().getUserName()); } else { holder.displayName.setText(msg.getFromUser().getNickname()); } } switch (msg.getStatus()) { case receive_fail: holder.picture.setImageResource(R.drawable.jmui_fetch_failed); break; default: } // 发送图片方,直接加载缩略图 } else { try { setPictureScale(path, holder.picture); Picasso.with(mContext).load(new File(path)).into(holder.picture); } catch (NullPointerException e) { Picasso.with(mContext).load(R.drawable.jmui_picture_not_found).into(holder.picture); } final Animation sendingAnim = AnimationUtils.loadAnimation(mContext, R.anim.jmui_rotate); LinearInterpolator lin = new LinearInterpolator(); sendingAnim.setInterpolator(lin); // 检查状态 switch (msg.getStatus()) { case send_success: holder.sendingIv.clearAnimation(); holder.sendingIv.setVisibility(View.GONE); holder.picture.setAlpha(1.0f); holder.progressTv.setVisibility(View.GONE); holder.resend.setVisibility(View.GONE); break; case send_fail: holder.sendingIv.clearAnimation(); holder.sendingIv.setVisibility(View.GONE); holder.picture.setAlpha(1.0f); holder.progressTv.setVisibility(View.GONE); holder.resend.setVisibility(View.VISIBLE); break; case send_going: sendingImage(holder, sendingAnim, msg); break; default: holder.picture.setAlpha(0.75f); holder.sendingIv.setVisibility(View.VISIBLE); holder.sendingIv.startAnimation(sendingAnim); holder.progressTv.setVisibility(View.VISIBLE); holder.progressTv.setText("0%"); holder.resend.setVisibility(View.GONE); // 从别的界面返回聊天界面,继续发送 if (!mMsgQueue.isEmpty()) { Message message = mMsgQueue.element(); if (message.getId() == msg.getId()) { Log.d(TAG, "Start sending message"); JMessageClient.sendMessage(message); mSendMsgId = message.getId(); sendingImage(holder, sendingAnim, message); } } } // 点击重发按钮,重发图片 holder.resend.setOnClickListener( new OnClickListener() { @Override public void onClick(View arg0) { showResendDialog(holder, sendingAnim, msg); } }); } if (holder.picture != null) { // TODO 点击图片事件 holder.picture.setOnLongClickListener( new OnLongClickListener() { @Override public boolean onLongClick(View v) { String name = msg.getFromUser().getUserName(); OnClickListener listener = new OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.copy_msg_btn: break; case R.id.forward_msg_btn: mDialog.dismiss(); break; case R.id.delete_msg_btn: mConv.deleteMessage(msg.getId()); mMsgList.remove(position); notifyDataSetChanged(); mDialog.dismiss(); break; } } }; mDialog = DialogCreator.createLongPressMessageDialog(mContext, name, true, listener); mDialog.show(); mDialog .getWindow() .setLayout((int) (0.8 * mWidth), WindowManager.LayoutParams.WRAP_CONTENT); return true; } }); } }
@Override public int getItemViewType(int position) { Message msg = mMsgList.get(position); return msg.getDirect().equals(MessageDirect.send) ? TYPE_SEND_TXT : TYPE_RECEIVE_TXT; }