package com.netease.nim.uikit.session.viewholder;
import android.graphics.Color;
import android.graphics.drawable.AnimationDrawable;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.netease.nim.uikit.R;
import com.netease.nim.uikit.common.media.audioplayer.Playable;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseMultiItemFetchLoadAdapter;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.netease.nim.uikit.common.util.sys.TimeUtil;
import com.netease.nim.uikit.session.audio.MessageAudioControl;
import com.netease.nimlib.sdk.msg.attachment.AudioAttachment;
import com.netease.nimlib.sdk.msg.constant.AttachStatusEnum;
import com.netease.nimlib.sdk.msg.constant.MsgDirectionEnum;
import com.netease.nimlib.sdk.msg.constant.MsgStatusEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
/**
* Created by zhoujianghua on 2015/8/5.
*/
public class MsgViewHolderAudio extends MsgViewHolderBase {
public MsgViewHolderAudio(BaseMultiItemFetchLoadAdapter adapter) {
super(adapter);
}
public static int MAX_AUDIO_TIME_SECOND = 120;
public static final int CLICK_TO_PLAY_AUDIO_DELAY = 500;
private TextView durationLabel;
private View containerView;
private View unreadIndicator;
private ImageView animationView;
private MessageAudioControl audioControl;
@Override
protected int getContentResId() {
return R.layout.nim_message_item_audio;
}
@Override
protected void inflateContentView() {
durationLabel = findViewById(R.id.message_item_audio_duration);
containerView = findViewById(R.id.message_item_audio_container);
unreadIndicator = findViewById(R.id.message_item_audio_unread_indicator);
animationView = findViewById(R.id.message_item_audio_playing_animation);
animationView.setBackgroundResource(0);
audioControl = MessageAudioControl.getInstance(context);
}
@Override
protected void bindContentView() {
layoutByDirection();
refreshStatus();
controlPlaying();
}
@Override
protected void onItemClick() {
if (audioControl != null) {
if (message.getDirect() == MsgDirectionEnum.In && message.getAttachStatus() != AttachStatusEnum.transferred) {
return;
}
if (message.getStatus() != MsgStatusEnum.read) {
// 将未读标识去掉,更新数据库
unreadIndicator.setVisibility(View.GONE);
}
initPlayAnim(); // 设置语音播放动画
audioControl.startPlayAudioDelay(CLICK_TO_PLAY_AUDIO_DELAY, message, onPlayListener);
audioControl.setPlayNext(true, adapter, message);
}
}
private void layoutByDirection() {
if (isReceivedMessage()) {
setGravity(animationView, Gravity.LEFT | Gravity.CENTER_VERTICAL);
setGravity(durationLabel, Gravity.RIGHT | Gravity.CENTER_VERTICAL);
containerView.setBackgroundResource(R.drawable.nim_message_item_left_selector);
containerView.setPadding(ScreenUtil.dip2px(15), ScreenUtil.dip2px(8), ScreenUtil.dip2px(10), ScreenUtil.dip2px(8));
animationView.setBackgroundResource(R.drawable.nim_audio_animation_list_left);
durationLabel.setTextColor(Color.BLACK);
} else {
setGravity(animationView, Gravity.RIGHT | Gravity.CENTER_VERTICAL);
setGravity(durationLabel, Gravity.LEFT | Gravity.CENTER_VERTICAL);
unreadIndicator.setVisibility(View.GONE);
containerView.setBackgroundResource(R.drawable.nim_message_item_right_selector);
containerView.setPadding(ScreenUtil.dip2px(10), ScreenUtil.dip2px(8), ScreenUtil.dip2px(15), ScreenUtil.dip2px(8));
animationView.setBackgroundResource(R.drawable.nim_audio_animation_list_right);
durationLabel.setTextColor(Color.WHITE);
}
}
private void refreshStatus() {// 消息状态
AudioAttachment attachment = (AudioAttachment) message.getAttachment();
MsgStatusEnum status = message.getStatus();
AttachStatusEnum attachStatus = message.getAttachStatus();
// alert button
if (TextUtils.isEmpty(attachment.getPath())) {
if (attachStatus == AttachStatusEnum.fail || status == MsgStatusEnum.fail) {
alertButton.setVisibility(View.VISIBLE);
} else {
alertButton.setVisibility(View.GONE);
}
}
// progress bar indicator
if (status == MsgStatusEnum.sending || attachStatus == AttachStatusEnum.transferring) {
progressBar.setVisibility(View.VISIBLE);
} else {
progressBar.setVisibility(View.GONE);
}
// unread indicator
if (isReceivedMessage() && attachStatus == AttachStatusEnum.transferred && status != MsgStatusEnum.read) {
unreadIndicator.setVisibility(View.VISIBLE);
} else {
unreadIndicator.setVisibility(View.GONE);
}
}
private void controlPlaying() {
final AudioAttachment msgAttachment = (AudioAttachment) message.getAttachment();
long duration = msgAttachment.getDuration();
setAudioBubbleWidth(duration);
if (!isMessagePlaying(audioControl, message)) {
if (audioControl.getAudioControlListener() != null
&& audioControl.getAudioControlListener().equals(onPlayListener)) {
audioControl.changeAudioControlListener(null);
}
updateTime(duration);
stop();
} else {
audioControl.changeAudioControlListener(onPlayListener);
play();
}
}
public static int getAudioMaxEdge() {
return (int) (0.6 * ScreenUtil.screenMin);
}
public static int getAudioMinEdge() {
return (int) (0.1875 * ScreenUtil.screenMin);
}
private void setAudioBubbleWidth(long milliseconds) {
long seconds = TimeUtil.getSecondsByMilliseconds(milliseconds);
int currentBubbleWidth = calculateBubbleWidth(seconds, MAX_AUDIO_TIME_SECOND);
ViewGroup.LayoutParams layoutParams = containerView.getLayoutParams();
layoutParams.width = currentBubbleWidth;
containerView.setLayoutParams(layoutParams);
}
private int calculateBubbleWidth(long seconds, int MAX_TIME) {
int maxAudioBubbleWidth = getAudioMaxEdge();
int minAudioBubbleWidth = getAudioMinEdge();
int currentBubbleWidth;
if (seconds <= 0) {
currentBubbleWidth = minAudioBubbleWidth;
} else if (seconds > 0 && seconds <= MAX_TIME) {
currentBubbleWidth = (int) ((maxAudioBubbleWidth - minAudioBubbleWidth) * (2.0 / Math.PI)
* Math.atan(seconds / 10.0) + minAudioBubbleWidth);
} else {
currentBubbleWidth = maxAudioBubbleWidth;
}
if (currentBubbleWidth < minAudioBubbleWidth) {
currentBubbleWidth = minAudioBubbleWidth;
} else if (currentBubbleWidth > maxAudioBubbleWidth) {
currentBubbleWidth = maxAudioBubbleWidth;
}
return currentBubbleWidth;
}
private void updateTime(long milliseconds) {
long seconds = TimeUtil.getSecondsByMilliseconds(milliseconds);
if (seconds >= 0) {
durationLabel.setText(seconds + "\"");
} else {
durationLabel.setText("");
}
}
protected boolean isMessagePlaying(MessageAudioControl audioControl, IMMessage message) {
if (audioControl.getPlayingAudio() != null && audioControl.getPlayingAudio().isTheSame(message)) {
return true;
} else {
return false;
}
}
private MessageAudioControl.AudioControlListener onPlayListener = new MessageAudioControl.AudioControlListener() {
@Override
public void updatePlayingProgress(Playable playable, long curPosition) {
if (curPosition > playable.getDuration()) {
return;
}
updateTime(curPosition);
}
@Override
public void onAudioControllerReady(Playable playable) {
play();
}
@Override
public void onEndPlay(Playable playable) {
updateTime(playable.getDuration());
stop();
}
};
private void play() {
if (animationView.getBackground() instanceof AnimationDrawable) {
AnimationDrawable animation = (AnimationDrawable) animationView.getBackground();
animation.start();
}
}
private void stop() {
if (animationView.getBackground() instanceof AnimationDrawable) {
AnimationDrawable animation = (AnimationDrawable) animationView.getBackground();
animation.stop();
endPlayAnim();
}
}
private void initPlayAnim() {
if (isReceivedMessage()) {
animationView.setBackgroundResource(R.drawable.nim_audio_animation_list_left);
} else {
animationView.setBackgroundResource(R.drawable.nim_audio_animation_list_right);
}
}
private void endPlayAnim() {
if (isReceivedMessage()) {
animationView.setBackgroundResource(R.drawable.nim_audio_animation_list_left_3);
} else {
animationView.setBackgroundResource(R.drawable.nim_audio_animation_list_right_3);
}
}
// @Override
// public void reclaim() {
// super.reclaim();
// if (audioControl.getAudioControlListener() != null
// && audioControl.getAudioControlListener().equals(onPlayListener)) {
// audioControl.changeAudioControlListener(null);
// }
// }
@Override
protected int leftBackground() {
return 0;
}
@Override
protected int rightBackground() {
return 0;
}
}