package com.netease.nim.uikit.recent.holder;
import android.graphics.drawable.AnimationDrawable;
import android.os.Handler;
import android.text.style.ImageSpan;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.netease.nim.uikit.R;
import com.netease.nim.uikit.cache.TeamDataCache;
import com.netease.nim.uikit.common.ui.drop.DropFake;
import com.netease.nim.uikit.common.ui.drop.DropManager;
import com.netease.nim.uikit.common.ui.imageview.HeadImageView;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseQuickAdapter;
import com.netease.nim.uikit.common.ui.recyclerview.holder.BaseViewHolder;
import com.netease.nim.uikit.common.ui.recyclerview.holder.RecyclerViewHolder;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.netease.nim.uikit.common.util.sys.TimeUtil;
import com.netease.nim.uikit.recent.RecentContactsCallback;
import com.netease.nim.uikit.recent.RecentContactsFragment;
import com.netease.nim.uikit.recent.adapter.RecentContactAdapter;
import com.netease.nim.uikit.session.emoji.MoonUtil;
import com.netease.nim.uikit.uinfo.UserInfoHelper;
import com.netease.nimlib.sdk.msg.constant.MsgStatusEnum;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.netease.nimlib.sdk.team.model.Team;
public abstract class RecentViewHolder extends RecyclerViewHolder<BaseQuickAdapter, BaseViewHolder, RecentContact> {
public RecentViewHolder(BaseQuickAdapter adapter) {
super(adapter);
}
private int lastUnreadCount = 0;
protected FrameLayout portraitPanel;
protected HeadImageView imgHead;
protected TextView tvNickname;
protected TextView tvMessage;
protected TextView tvDatetime;
// 消息发送错误状态标记,目前没有逻辑处理
protected ImageView imgMsgStatus;
protected View bottomLine;
protected View topLine;
// 未读红点(一个占坑,一个全屏动画)
protected DropFake tvUnread;
private ImageView imgUnreadExplosion;
protected TextView tvOnlineState;
// 子类覆写
protected abstract String getContent(RecentContact recent);
@Override
public void convert(BaseViewHolder holder, RecentContact data, int position, boolean isScrolling) {
inflate(holder, data);
refresh(holder, data, position);
}
public void inflate(BaseViewHolder holder, final RecentContact recent) {
this.portraitPanel = holder.getView(R.id.portrait_panel);
this.imgHead = holder.getView(R.id.img_head);
this.tvNickname = holder.getView(R.id.tv_nickname);
this.tvMessage = holder.getView(R.id.tv_message);
this.tvUnread = holder.getView(R.id.unread_number_tip);
this.imgUnreadExplosion = holder.getView(R.id.unread_number_explosion);
this.tvDatetime = holder.getView(R.id.tv_date_time);
this.imgMsgStatus = holder.getView(R.id.img_msg_status);
this.bottomLine = holder.getView(R.id.bottom_line);
this.topLine = holder.getView(R.id.top_line);
this.tvOnlineState = holder.getView(R.id.tv_online_state);
holder.addOnClickListener(R.id.unread_number_tip);
this.tvUnread.setTouchListener(new DropFake.ITouchListener() {
@Override
public void onDown() {
DropManager.getInstance().setCurrentId(recent);
DropManager.getInstance().down(tvUnread, tvUnread.getText());
}
@Override
public void onMove(float curX, float curY) {
DropManager.getInstance().move(curX, curY);
}
@Override
public void onUp() {
DropManager.getInstance().up();
}
});
}
public void refresh(BaseViewHolder holder, RecentContact recent, final int position) {
// unread count animation
boolean shouldBoom = lastUnreadCount > 0 && recent.getUnreadCount() == 0; // 未读数从N->0执行爆裂动画;
lastUnreadCount = recent.getUnreadCount();
updateBackground(holder, recent, position);
loadPortrait(recent);
updateNickLabel(UserInfoHelper.getUserTitleName(recent.getContactId(), recent.getSessionType()));
updateOnlineState(recent);
updateMsgLabel(holder, recent);
updateNewIndicator(recent);
if (shouldBoom) {
Object o = DropManager.getInstance().getCurrentId();
if (o instanceof String && o.equals("0")) {
imgUnreadExplosion.setImageResource(R.drawable.explosion);
imgUnreadExplosion.setVisibility(View.VISIBLE);
new Handler().post(new Runnable() {
@Override
public void run() {
((AnimationDrawable) imgUnreadExplosion.getDrawable()).start();
// 解决部分手机动画无法播放的问题(例如华为荣耀)
getAdapter().notifyItemChanged(getAdapter().getViewHolderPosition(position));
}
});
}
} else {
imgUnreadExplosion.setVisibility(View.GONE);
}
}
private void updateBackground(BaseViewHolder holder, RecentContact recent, int position) {
topLine.setVisibility(getAdapter().isFirstDataItem(position) ? View.GONE : View.VISIBLE);
bottomLine.setVisibility(getAdapter().isLastDataItem(position) ? View.VISIBLE : View.GONE);
if ((recent.getTag() & RecentContactsFragment.RECENT_TAG_STICKY) == 0) {
holder.getConvertView().setBackgroundResource(R.drawable.touch_bg);
} else {
holder.getConvertView().setBackgroundResource(R.drawable.nim_recent_contact_sticky_selecter);
}
}
protected void loadPortrait(RecentContact recent) {
// 设置头像
if (recent.getSessionType() == SessionTypeEnum.P2P) {
imgHead.loadBuddyAvatar(recent.getContactId());
} else if (recent.getSessionType() == SessionTypeEnum.Team) {
Team team = TeamDataCache.getInstance().getTeamById(recent.getContactId());
imgHead.loadTeamIconByTeam(team);
}
}
private void updateNewIndicator(RecentContact recent) {
int unreadNum = recent.getUnreadCount();
tvUnread.setVisibility(unreadNum > 0 ? View.VISIBLE : View.GONE);
tvUnread.setText(unreadCountShowRule(unreadNum));
}
private void updateMsgLabel(BaseViewHolder holder, RecentContact recent) {
// 显示消息具体内容
MoonUtil.identifyRecentVHFaceExpressionAndTags(holder.getContext(), tvMessage, getContent(recent), -1, 0.45f);
//tvMessage.setText(getContent());
MsgStatusEnum status = recent.getMsgStatus();
switch (status) {
case fail:
imgMsgStatus.setImageResource(R.drawable.nim_g_ic_failed_small);
imgMsgStatus.setVisibility(View.VISIBLE);
break;
case sending:
imgMsgStatus.setImageResource(R.drawable.nim_recent_contact_ic_sending);
imgMsgStatus.setVisibility(View.VISIBLE);
break;
default:
imgMsgStatus.setVisibility(View.GONE);
break;
}
String timeString = TimeUtil.getTimeShowString(recent.getTime(), true);
tvDatetime.setText(timeString);
}
protected String getOnlineStateContent(RecentContact recent) {
return "";
}
protected void updateOnlineState(RecentContact recent) {
if (recent.getSessionType() == SessionTypeEnum.Team) {
tvOnlineState.setVisibility(View.GONE);
} else {
tvOnlineState.setVisibility(View.VISIBLE);
tvOnlineState.setText(getOnlineStateContent(recent));
}
}
protected void updateNickLabel(String nick) {
int labelWidth = ScreenUtil.screenWidth;
labelWidth -= ScreenUtil.dip2px(50 + 70); // 减去固定的头像和时间宽度
if (labelWidth > 0) {
tvNickname.setMaxWidth(labelWidth);
}
tvNickname.setText(nick);
}
protected String unreadCountShowRule(int unread) {
unread = Math.min(unread, 99);
return String.valueOf(unread);
}
protected RecentContactsCallback getCallback() {
return ((RecentContactAdapter) getAdapter()).getCallback();
}
}