package com.xscm.modulemain; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static com.xscm.moduleutil.base.CommonAppContext.postDelayed; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; import android.media.MediaPlayer; import android.os.Bundle; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.style.ForegroundColorSpan; import android.util.DisplayMetrics; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.AccelerateInterpolator; import android.view.animation.Animation; import android.view.animation.DecelerateInterpolator; import android.view.animation.TranslateAnimation; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.databinding.ViewDataBinding; import com.blankj.utilcode.util.ActivityUtils; import com.blankj.utilcode.util.GsonUtils; import com.blankj.utilcode.util.LogUtils; import com.blankj.utilcode.util.ToastUtils; import com.tencent.imsdk.v2.V2TIMSDKListener; import com.tencent.imsdk.v2.V2TIMValueCallback; import com.tencent.qcloud.tuikit.tuichat.bean.ChatInfo; import com.xscm.modulemain.activity.WebViewActivity; import com.xscm.modulemain.activity.main.activity.MainActivity; import com.xscm.modulemain.activity.room.activity.RoomActivity; import com.xscm.modulemain.activity.user.activity.DailyTasksActivity; import com.xscm.modulemain.activity.user.activity.HeartCpActivity; import com.xscm.modulemain.activity.user.activity.MyRoomActivity; import com.xscm.modulemain.manager.RoomManager; import com.xscm.moduleutil.BaseEvent; import com.xscm.moduleutil.R; import com.xscm.moduleutil.activity.BaseAppCompatActivity; import com.xscm.moduleutil.activity.IPresenter; import com.xscm.moduleutil.activity.IView; import com.xscm.moduleutil.base.CommonAppContext; import com.xscm.moduleutil.base.WebUrlConstants; import com.xscm.moduleutil.bean.RoomGiftData; import com.xscm.moduleutil.bean.RoomMessageEvent; import com.xscm.moduleutil.bean.UserBean; import com.xscm.moduleutil.bean.XLHBean; import com.xscm.moduleutil.dialog.ConfirmDialog; import com.xscm.moduleutil.event.HourlyBean; import com.xscm.moduleutil.event.MqttBean; import com.xscm.moduleutil.event.RedBean; import com.xscm.moduleutil.event.UnreadCountEvent; import com.xscm.moduleutil.http.BaseObserver; import com.xscm.moduleutil.http.RetrofitClient; import com.xscm.moduleutil.listener.CPListener; import com.xscm.moduleutil.listener.MessageListenerSingleton; import com.xscm.moduleutil.utils.ClickUtils; import com.xscm.moduleutil.utils.ImageUtils; import com.xscm.moduleutil.utils.LanguageUtil; import com.tencent.imsdk.v2.V2TIMManager; import com.tencent.imsdk.v2.V2TIMUserFullInfo; import com.tencent.qcloud.tuicore.TUILogin; import com.tencent.qcloud.tuicore.interfaces.TUICallback; import com.xscm.moduleutil.utils.SpUtil; import com.xscm.moduleutil.utils.SystemUtils; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import org.jetbrains.annotations.NotNull; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.TimeUnit; import io.reactivex.disposables.Disposable; public abstract class BaseMvpActivity

extends BaseAppCompatActivity implements IView { protected P MvpPre; private ConfirmDialog confirmDialog; protected abstract P bindPresenter(); @Override protected void doDone() { super.doDone(); } @Override protected void initView() { MvpPre = bindPresenter(); } @Override public void showLoadings() { showLoading(); } @Override public void showLoadings(String content) { showLoading(content); } @Override public void disLoadings() { disLoading(); } private Activity mThis; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); mThis = this; RetrofitClient.getInstance().CpListener(new CPListener() { @Override public void onReceiveMsg(@NotNull RoomMessageEvent roomMessageEvent) { cpReceiver(roomMessageEvent); } @Override public void onSendCpMsg(@NotNull RoomGiftData gitData) { cpMsg(gitData); } }); RetrofitClient.getInstance().setJoinRoomLoadListener(result -> { if (mThis instanceof MainActivity) { ((MainActivity) mThis).isShowLoading(false); } else if (mThis instanceof MyRoomActivity) { ((MyRoomActivity) mThis).isShowLoading(false); } else if (mThis instanceof DailyTasksActivity) { ((DailyTasksActivity) mThis).isShowLoading(false); } }); } @Override protected void onDestroy() { ClickUtils.clearAllClickRecords(); // 清理MQTT相关资源 synchronized (mqttQueueLock) { mqttMessageQueue.clear(); isMqttPlaying = false; } // 清理XLH相关资源 synchronized (xlhQueueLock) { xlhMessageQueue.clear(); isXlhPlaying = false; } // 移除当前显示的视图 try { if (currentMqttView != null && currentMqttView.getParent() != null) { ViewGroup parent = (ViewGroup) currentMqttView.getParent(); parent.removeView(currentMqttView); } currentMqttView = null; if (currentXlhView != null && currentXlhView.getParent() != null) { ViewGroup parent = (ViewGroup) currentXlhView.getParent(); parent.removeView(currentXlhView); } currentXlhView = null; } catch (Exception e) { LogUtils.e("清理飘屏视图失败", e); } if (MvpPre != null) { try { MvpPre.detachView(); } catch (Exception e) { e.printStackTrace(); } } super.onDestroy(); } @Override public Activity getSelfActivity() { return this; } @Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(LanguageUtil.attachBaseContext(newBase)); } public void cpMsg(RoomGiftData event) { String cpTypeJson = GsonUtils.toJson(event.getCp_type()); if (event.getCp_type().getCp_type() == 1) { if (event.getGift_user_data() != null && event.getGift_user_data().size() > 0) { for (int i = 0; i < event.getGift_user_data().size(); i++) // 创建自定义消息 MessageListenerSingleton.getInstance().sendCustomC2CMessage(130, cpTypeJson, event.getGift_user_data().get(i).getUser_id() ); } } else if (event.getCp_type().getCp_type() == 2) { if (event.getGift_user_data() != null && event.getGift_user_data().size() > 0) { for (int i = 0; i < event.getGift_user_data().size(); i++) // 创建自定义消息 MessageListenerSingleton.getInstance().sendCustomC2CMessage(131, cpTypeJson, event.getGift_user_data().get(i).getUser_id() ); } } } public void cpReceiver(BaseEvent event) { String a = ActivityUtils.getTopActivity().getLocalClassName(); if (event instanceof RoomMessageEvent) { com.xscm.moduleutil.bean.RoomGiftData.CpType text = GsonUtils.fromJson(((RoomMessageEvent) event).getText().getText().toString(), com.xscm.moduleutil.bean.RoomGiftData.CpType.class); if (text.getCp_type() == 1) { queren1(1, text.getText1(), text.getGift_id() + "", ((RoomMessageEvent) event).getText().getFromUserInfo().getUser_id() + "", ((RoomMessageEvent) event).getRoomId()); } else if (text.getCp_type() == 2) { queren1(2, text.getText1(), text.getGift_id() + "", ((RoomMessageEvent) event).getText().getFromUserInfo().getUser_id() + "", ((RoomMessageEvent) event).getRoomId()); } } } // TODO: 2025/11/19 登录腾讯 @Subscribe(threadMode = ThreadMode.MAIN) public void logOutEvent(UserBean userBean) { // 在用户 UI 点击登录的时候调用 TUILogin.login(getBaseContext(), CommonAppContext.getInstance().getCurrentEnvironment().getSdkAppId(), "u" + userBean.getUser_id(), userBean.getTencent_im(), new TUICallback() { @Override public void onError(final int code, final String desc) { LogUtils.e("@@@1", code, "描述:", desc); } @Override public void onSuccess() { LogUtils.e("@@@", "成功"); V2TIMManager.getConversationManager().getTotalUnreadMessageCount(new V2TIMValueCallback() { @Override public void onSuccess(Long aLong) { // 通知未读数变化 UnreadCountEvent event = CommonAppContext.getInstance().unreadCountEvent; if (event == null) { event = new UnreadCountEvent(); } event.setALong(aLong); // 使用EventBus通知 CommonAppContext.getInstance().setUnreadCountEvent(event); EventBus.getDefault().post(event); } @Override public void onError(int code, String desc) { // 错误处理 } }); //initLocation(); } }); // V2TIMManager.getInstance().addIMSDKListener(imSdkListener); } private final V2TIMSDKListener imSdkListener = new V2TIMSDKListener() { @Override public void onConnecting() { } @Override public void onConnectSuccess() {//重连成功 if (CommonAppContext.getInstance().playId != null) { LogUtils.e("@@@", "重连成功"); LogUtils.e("@@@", "" + CommonAppContext.getInstance().playId); // RetrofitClient.getInstance().roomUserReconnect(CommonAppContext.getInstance().playId); } } @Override public void onConnectFailed(int code, String error) { LogUtils.e("@@@", "断开连接"); CommonAppContext.getInstance().onConnectFailed = true; } @Override public void onKickedOffline() { // queren1(); if (CommonAppContext.getInstance().playId != null) { ToastUtils.showShort("您的账号已被挤下线"); try { CommonAppContext.getInstance().clearLoginInfo(); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } } @Override public void onUserSigExpired() { } @Override public void onSelfInfoUpdated(V2TIMUserFullInfo info) { } }; private void queren1(int type, String content, String giftid, String userId, String roomId) { // 创建并显示确认对话框 new ConfirmDialog(ActivityUtils.getTopActivity(), type == 1 ? "心动信号" : "缘定三生 此刻同心", content, type == 1 ? "回赠同心锁" : "进入心动空间", type == 1 ? "再想想" : "我知道了", v -> { if (type == 1) { // 点击“确认”按钮时执行删除操作 RetrofitClient.getInstance().cpGiveGift(userId, giftid, roomId, new BaseObserver() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(RoomGiftData roomGiftData) { if (roomGiftData.getCp_type() != null) { if (roomGiftData.getCp_type().getCp_type() == 2) { queren1(2, roomGiftData.getCp_type().getText(), "", SpUtil.getUserId() + "", ""); } } } }); } else { int userids = Integer.parseInt(userId); Intent intent = new Intent(ActivityUtils.getTopActivity(), HeartCpActivity.class); intent.putExtra("userId", userids); startActivity(intent); } }, v -> { // 点击“取消”按钮时什么都不做 }, false, 0).show(); } @Override public Resources getResources() { Resources resources = super.getResources(); if (resources != null) { Configuration configuration = resources.getConfiguration(); if (configuration != null) { // 设置字体缩放比例不随系统变化 configuration.fontScale = 1.0f; // 1.0f表示默认大小 resources.updateConfiguration(configuration, resources.getDisplayMetrics()); } } return resources; } /// 礼物特效 /// 礼物特效 // 在类中添加以下成员变量 private final List mqttMessageQueue = new ArrayList<>(); // MQTT消息队列 private final List xlhMessageQueue = new ArrayList<>(); // XLH消息队列 private final List redMessageQueue = new ArrayList<>(); // 红包队列 private boolean isMqttPlaying = false; // MQTT播放状态标志 private boolean isXlhPlaying = false; // XLH播放状态标志 private boolean isRedPlaying = false; // XLH播放状态标志 private final Object mqttQueueLock = new Object(); // MQTT队列同步锁 private final Object xlhQueueLock = new Object(); // XLH队列同步锁 private final Object RedQueueLock = new Object(); // XLH队列同步锁 private View currentMqttView = null; // 当前正在播放的MQTT视图 private View currentXlhView = null; // 当前正在播放的XLH视图 private View currentRedView = null; // 当前正在播放的XLH视图 private final List hourlyMessageQueue = new ArrayList<>(); // 小时榜消息队列 private final Map currentHourlyViews = new HashMap<>(); // 当前显示的小时榜视图 private final Object hourlyQueueLock = new Object(); // 小时榜队列同步锁 private boolean isHourlyProcessing = false; // 小时榜处理状态标志 // TODO: 2025/11/19 收到小时榜 @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageReceived(List hourlyBean) { LogUtils.e("收到小时榜", hourlyBean); if (hourlyBean == null) return; if (SpUtil.getFloatingScreen() == 1) { synchronized (hourlyQueueLock) { hourlyMessageQueue.addAll(hourlyBean); if (!isHourlyProcessing) { isHourlyProcessing = true; processHourlyMessages(); } } } else { hourlyMessageQueue.clear(); clearAllHourlyViews(); } } private void processHourlyMessages() { List messagesToProcess; synchronized (hourlyQueueLock) { if (hourlyMessageQueue.isEmpty()) { isHourlyProcessing = false; return; } // 每次只处理1条数据 messagesToProcess = new ArrayList<>(); messagesToProcess.add(hourlyMessageQueue.remove(0)); } // 只展示一条数据 HourlyBean bean = messagesToProcess.get(0); showHourlyFloatingMessage(bean, 0); } private void showHourlyFloatingMessage(HourlyBean hourlyBean, int positionIndex) { try { ViewGroup decorView = (ViewGroup) getWindow().getDecorView(); // 创建新的视图 View hourlyView = LayoutInflater.from(this).inflate(com.xscm.moduleutil.R.layout.item_hourly_floating, null); FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT); // 设置固定的垂直位置 int baseMargin = com.sunfusheng.marqueeview.DisplayUtil.dip2px(this, 70); layoutParams.topMargin = baseMargin; layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; hourlyView.setLayoutParams(layoutParams); decorView.addView(hourlyView); // 保存视图引用 currentHourlyViews.put(positionIndex, hourlyView); // 更新视图数据 updateHourlyFloatingViewData(hourlyView, hourlyBean); // 根据类型获取展示时间 long displayDuration = getDisplayDurationByType(Integer.parseInt(hourlyBean.getRank_number())); // 启动动画 resetAndStartHourlyAnimation(hourlyView, displayDuration, () -> { // 动画结束后清理视图 if (hourlyView.getParent() != null) { decorView.removeView(hourlyView); } currentHourlyViews.remove(positionIndex); // 检查是否还有更多消息需要处理 synchronized (hourlyQueueLock) { if (hourlyMessageQueue.isEmpty()) { isHourlyProcessing = false; } else { // 当前视图消失后处理下一条消息 processHourlyMessages(); } } }); } catch (Exception e) { LogUtils.e("显示小时榜飘屏失败", e); } } private long getDisplayDurationByType(int type) { // 根据不同类型设置不同的展示时间(毫秒) switch (type) { case 1: // 第一名 return 5000; // 5秒 case 2: // 第二名 return 4000; // 4秒 case 3: // 第三名 return 3000; // 3秒 default: return 3000; // 默认3秒 } } private void updateHourlyFloatingViewData(View view, HourlyBean hourlyBean) { TextView tvName = view.findViewById(com.xscm.moduleutil.R.id.tv_name); ImageView ivAvatar = view.findViewById(com.xscm.moduleutil.R.id.im_h_t); if (hourlyBean != null) { // 根据排名设置不同的显示 switch (hourlyBean.getRank_number()) { case "1": // tvName.setText("新科状元! ["+hourlyBean.getRoom_name()+"] 独占鳌头!"); setColoredText(tvName, "新科状元! [", hourlyBean.getRoom_name(), "] 独占鳌头!", com.xscm.moduleutil.R.color.color_FFFA63); ivAvatar.setImageResource(com.xscm.moduleutil.R.mipmap.hourl_top1); break; case "2": // tvName.setText("金榜榜眼! ["+hourlyBean.getRoom_name()+"] 才气逼人!"); setColoredText(tvName, "金榜榜眼! [", hourlyBean.getRoom_name(), "] 才气逼人!", com.xscm.moduleutil.R.color.color_FFFA63); ivAvatar.setImageResource(com.xscm.moduleutil.R.mipmap.hourl_top2); break; case "3": setColoredText(tvName, "风采探花! [", hourlyBean.getRoom_name(), "] 实力绽放!", com.xscm.moduleutil.R.color.color_1FFFE5); // tvName.setText("风采探花! ["+hourlyBean.getRoom_name()+"] 实力绽放!"); ivAvatar.setImageResource(com.xscm.moduleutil.R.mipmap.hourl_top3); break; default: tvName.setVisibility(GONE); ivAvatar.setVisibility(GONE); break; } } } // 设置带颜色的文本 // 设置带颜色的文本 private void setColoredText(TextView textView, String prefix, String roomName, String suffix, int colorRes) { String fullText = prefix + roomName + suffix; SpannableStringBuilder builder = new SpannableStringBuilder(fullText); // 先为整个文本设置白色 builder.setSpan( new ForegroundColorSpan(ContextCompat.getColor(this, R.color.white)), 0, fullText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ); // 查找房间名在文本中的位置 int start = fullText.indexOf("["); int end = fullText.indexOf("]") + 1; if (start >= 0 && end > start) { // 为房间名部分设置指定颜色 builder.setSpan( new ForegroundColorSpan(ContextCompat.getColor(this, colorRes)), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ); } textView.setText(builder); } private void resetAndStartHourlyAnimation(View view, long displayDuration, Runnable onAnimationEnd) { try { int screenWidth = getScreenWidth(); // 设置初始位置:在屏幕右侧外部 view.setTranslationX(screenWidth); // 进入动画 ObjectAnimator enterAnimator = ObjectAnimator.ofFloat(view, "translationX", screenWidth, 0f); enterAnimator.setDuration(500); enterAnimator.setInterpolator(new DecelerateInterpolator()); enterAnimator.start(); // 停留后退出动画 view.postDelayed(() -> { try { ObjectAnimator exitAnimator = ObjectAnimator.ofFloat(view, "translationX", 0f, -screenWidth); exitAnimator.setDuration(500); exitAnimator.setInterpolator(new AccelerateInterpolator()); exitAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { onAnimationEnd.run(); } @Override public void onAnimationCancel(Animator animation) { onAnimationEnd.run(); } }); exitAnimator.start(); } catch (Exception e) { LogUtils.e("小时榜退出动画执行失败", e); onAnimationEnd.run(); } }, displayDuration); // 根据类型设置的展示时间 } catch (Exception e) { LogUtils.e("小时榜动画启动失败", e); onAnimationEnd.run(); } } private void clearAllHourlyViews() { ViewGroup decorView = (ViewGroup) getWindow().getDecorView(); for (View view : currentHourlyViews.values()) { if (view.getParent() != null) { decorView.removeView(view); } } currentHourlyViews.clear(); } /// 礼物特效 - MQTT消息处理 @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageReceived(MqttBean mqttBean) { LogUtils.e("收到MQTT", mqttBean); if (mqttBean == null) return; if (SpUtil.getFloatingScreen() == 1) { synchronized (mqttQueueLock) { mqttMessageQueue.addAll(mqttBean.getList()); // if (!isMqttPlaying) { // isMqttPlaying = true; processNextMqttMessage(); // } } } else { mqttMessageQueue.clear(); } } /// XLH消息处理 @Subscribe(threadMode = ThreadMode.MAIN) public void onEvent(XLHBean event) { LogUtils.e("收到XLH", event); if (event == null) return; if (event.getText() == null || event.getText().isEmpty()) return; if (SpUtil.getFloatingScreen() == 1) { synchronized (xlhQueueLock) { xlhMessageQueue.add(event); if (!isXlhPlaying) { isXlhPlaying = true; processNextXlhMessage(); } } } else { xlhMessageQueue.clear(); } } @Subscribe(threadMode = ThreadMode.MAIN) public void onEvent(RedBean event) { LogUtils.e("收到红包", event); if (event == null) return; if (SpUtil.getFloatingScreen() == 1) { synchronized (RedQueueLock) { redMessageQueue.add(event); if (!isRedPlaying) { isRedPlaying = true; processNextRedMessage(); } } } else { redMessageQueue.clear(); } } private void processNextRedMessage() { RedBean redBean; synchronized (RedQueueLock) { if (redMessageQueue.isEmpty()) { isRedPlaying = false; return; } redBean = redMessageQueue.remove(0); } showPiaoPingMessageRed(redBean); } private void showPiaoPingMessageRed(RedBean redBean) { try { // 清理之前的视图(如果存在) if (currentRedView != null && currentRedView.getParent() != null) { ViewGroup parent = (ViewGroup) currentRedView.getParent(); parent.removeView(currentRedView); } if (decorView2 == null) { decorView2 = (ViewGroup) getWindow().getDecorView(); } currentRedView = LayoutInflater.from(this).inflate(com.xscm.moduleutil.R.layout.item_piaoping_red, null); FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT); layoutParams.topMargin = com.sunfusheng.marqueeview.DisplayUtil.dip2px(this, 140); layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; currentRedView.setLayoutParams(layoutParams); decorView2.addView(currentRedView); updateRedFloatingViewData(currentRedView, redBean); // 播放红包音效 if (SpUtil.getRedSound() == 1) { playRedPacketSound(); } resetAndStartXlhAnimation(currentRedView, () -> { // 清理当前视图 if (currentRedView != null && currentRedView.getParent() != null) { ViewGroup parent = (ViewGroup) currentRedView.getParent(); parent.removeView(currentRedView); } currentRedView = null; // 处理队列中的下一条消息 synchronized (RedQueueLock) { isRedPlaying = false; processNextRedMessage(); } }); } catch (Exception e) { LogUtils.e("显示红包飘屏失败", e); // 出现异常时继续处理队列 synchronized (RedQueueLock) { isRedPlaying = false; processNextRedMessage(); } } } // 在类中添加成员变量 private MediaPlayer redPacketMediaPlayer = null; private boolean isRedPacketMediaPrepared = false; // 添加播放红包音效的方法 private void playRedPacketSound() { try { if (!isRedPacketMediaPrepared) { // 第一次初始化MediaPlayer if (redPacketMediaPlayer == null) { redPacketMediaPlayer = MediaPlayer.create(this, com.xscm.moduleutil.R.raw.red_packet_come); // 假设音效文件名为red_packet_sound.mp3 redPacketMediaPlayer.setOnPreparedListener(mp -> { isRedPacketMediaPrepared = true; mp.start(); }); redPacketMediaPlayer.setOnCompletionListener(mp -> { // 播放完成后重置,以便下次重新播放 try { mp.seekTo(0); } catch (Exception e) { LogUtils.e("MediaPlayer重置失败", e); } }); } if (redPacketMediaPlayer != null) { redPacketMediaPlayer.prepareAsync(); // 异步准备 } } else { // 已经准备好了,直接重新播放 if (redPacketMediaPlayer != null && !redPacketMediaPlayer.isPlaying()) { redPacketMediaPlayer.seekTo(0); redPacketMediaPlayer.start(); } } } catch (Exception e) { LogUtils.e("播放红包音效失败", e); isRedPacketMediaPrepared = false; } } private void updateRedFloatingViewData(View view, RedBean redBean) { TextView textView = view.findViewById(R.id.tv_name); if (redBean != null) { String fullText = redBean.getText(); if (redBean.getNickname() != null && redBean.getRoom_name() != null) { SpannableStringBuilder builder = new SpannableStringBuilder(fullText); // 为用户名设置蓝色 int userNameStart = fullText.indexOf(redBean.getNickname()); if (userNameStart >= 0) { builder.setSpan( new ForegroundColorSpan(ContextCompat.getColor(this, com.xscm.moduleutil.R.color.colorPrimary)), userNameStart, userNameStart + redBean.getNickname().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ); } // 为房间名设置蓝色 int roomNameStart = fullText.indexOf(redBean.getRoom_name()); if (roomNameStart >= 0) { builder.setSpan( new ForegroundColorSpan(ContextCompat.getColor(this, com.xscm.moduleutil.R.color.colorPrimary)), roomNameStart, roomNameStart + redBean.getRoom_name().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ); } textView.setText(builder); } else { textView.setText(fullText); } } else { textView.setText(""); } view.setOnClickListener(v -> { // 点击时执行跳转操作 handleRedItemClick(redBean); }); } // 处理下一个MQTT消息 private void processNextMqttMessage() { MqttBean.ListBean mqttBean; synchronized (mqttQueueLock) { if (mqttMessageQueue.isEmpty()) { isMqttPlaying = false; return; } mqttBean = mqttMessageQueue.remove(0); } showFloatingMessage(mqttBean); } // 处理下一个XLH消息 private void processNextXlhMessage() { XLHBean xlhBean; synchronized (xlhQueueLock) { if (xlhMessageQueue.isEmpty()) { isXlhPlaying = false; return; } xlhBean = xlhMessageQueue.remove(0); } showPiaoPingMessageXlh(xlhBean); } ViewGroup decorView;//礼物的 ViewGroup decorView1;//巡乐会的 ViewGroup decorView2;//红包的 private void showFloatingMessage(MqttBean.ListBean mqttBean) { // QXGiftDriftView.getInstance( this).addGiftModel(mqttBean); try { // 清理之前的视图(如果存在) if (currentMqttView != null && currentMqttView.getParent() != null) { ViewGroup parent = (ViewGroup) currentMqttView.getParent(); parent.removeView(currentMqttView); } if (decorView == null) { decorView = (ViewGroup) getWindow().getDecorView(); } currentMqttView = LayoutInflater.from(this).inflate(com.xscm.moduleutil.R.layout.item_piaoping, null); FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT); layoutParams.topMargin = com.sunfusheng.marqueeview.DisplayUtil.dip2px(this, 70); layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; currentMqttView.setLayoutParams(layoutParams); decorView.addView(currentMqttView); updateFloatingViewData(currentMqttView, mqttBean); resetAndStartMqttAnimation(currentMqttView, () -> { // 清理当前视图 if (currentMqttView != null && currentMqttView.getParent() != null) { ViewGroup parent = (ViewGroup) currentMqttView.getParent(); parent.removeView(currentMqttView); } currentMqttView = null; // 处理队列中的下一条消息 synchronized (mqttQueueLock) { isMqttPlaying = false; processNextMqttMessage(); } }); } catch (Exception e) { LogUtils.e("显示MQTT飘屏失败", e); // 出现异常时继续处理队列 synchronized (mqttQueueLock) { isMqttPlaying = false; processNextMqttMessage(); } } } private void showPiaoPingMessageXlh(XLHBean event) { try { // 清理之前的视图(如果存在) if (currentXlhView != null && currentXlhView.getParent() != null) { ViewGroup parent = (ViewGroup) currentXlhView.getParent(); parent.removeView(currentXlhView); } if (decorView1 == null) { decorView1 = (ViewGroup) getWindow().getDecorView(); } currentXlhView = LayoutInflater.from(this).inflate(com.xscm.moduleutil.R.layout.item_piaoping_xlh, null); FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT); layoutParams.topMargin = com.sunfusheng.marqueeview.DisplayUtil.dip2px(this, 100); layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; currentXlhView.setLayoutParams(layoutParams); decorView1.addView(currentXlhView); updateXlhFloatingViewData(currentXlhView, event); resetAndStartXlhAnimation(currentXlhView, () -> { // 清理当前视图 if (currentXlhView != null && currentXlhView.getParent() != null) { ViewGroup parent = (ViewGroup) currentXlhView.getParent(); parent.removeView(currentXlhView); } currentXlhView = null; // 处理队列中的下一条消息 synchronized (xlhQueueLock) { isXlhPlaying = false; processNextXlhMessage(); } }); } catch (Exception e) { LogUtils.e("显示XLH飘屏失败", e); // 出现异常时继续处理队列 synchronized (xlhQueueLock) { isXlhPlaying = false; processNextXlhMessage(); } } } private void resetAndStartMqttAnimation(View view, Runnable onAnimationEnd) { try { int screenWidth = getScreenWidth(); // 设置初始位置:在屏幕右侧外部(完全不可见) view.setTranslationX(screenWidth); TranslateAnimation enterAnim = new TranslateAnimation( Animation.ABSOLUTE, screenWidth, Animation.ABSOLUTE, (screenWidth - SystemUtils.getWidth(316)) / 2, Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0 ); enterAnim.setDuration(1500); enterAnim.setInterpolator(new DecelerateInterpolator(2.0f)); enterAnim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { // 停留后退出 postDelayed(() -> { TranslateAnimation exitAnim = new TranslateAnimation( Animation.ABSOLUTE, (screenWidth - SystemUtils.getWidth(316)) / 2, Animation.ABSOLUTE, -screenWidth, Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0 ); exitAnim.setDuration(3000); exitAnim.setInterpolator(new DecelerateInterpolator(2f)); exitAnim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { // 移除视图并处理下一个 onAnimationEnd.run(); } @Override public void onAnimationRepeat(Animation animation) { } }); view.startAnimation(exitAnim); }, 5000); // 停留1秒 } @Override public void onAnimationRepeat(Animation animation) { } }); view.startAnimation(enterAnim); } catch (Exception e) { LogUtils.e("MQTT动画启动失败", e); onAnimationEnd.run(); } } // 添加获取屏幕宽度的方法 private int getScreenWidth() { DisplayMetrics displayMetrics = new DisplayMetrics(); if (getWindowManager() != null) { getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); return displayMetrics.widthPixels; } return getResources().getDisplayMetrics().widthPixels; } private void resetAndStartXlhAnimation(View view, Runnable onAnimationEnd) { try { view.setTranslationX(view.getWidth()); ObjectAnimator animator1 = ObjectAnimator.ofFloat(view, "translationX", view.getWidth(), 0f); animator1.setDuration(1500); animator1.setInterpolator(new DecelerateInterpolator(2.0f)); animator1.start(); view.postDelayed(() -> { try { ObjectAnimator animator2 = ObjectAnimator.ofFloat(view, "translationX", 0f, -view.getWidth()); animator2.setDuration(1500); animator2.setInterpolator(new DecelerateInterpolator(2.0f)); animator2.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { onAnimationEnd.run(); } @Override public void onAnimationCancel(Animator animation) { onAnimationEnd.run(); } }); animator2.start(); } catch (Exception e) { LogUtils.e("XLH动画执行失败", e); onAnimationEnd.run(); } }, 5000); } catch (Exception e) { LogUtils.e("XLH动画启动失败", e); onAnimationEnd.run(); } } private void updateFloatingViewData(View view, MqttBean.ListBean mqttBean) { TextView textView = view.findViewById(com.xscm.moduleutil.R.id.tv_name); TextView textView2 = view.findViewById(com.xscm.moduleutil.R.id.tv_to_name); TextView tv_time = view.findViewById(com.xscm.moduleutil.R.id.tv_num); if (mqttBean != null) { if (TextUtils.isEmpty(mqttBean.getToUserName())){ textView2.setVisibility(GONE); textView.setText(mqttBean.getText()); }else { textView2.setVisibility(VISIBLE); textView2.setText("送给" + (mqttBean.getToUserName() != null ? mqttBean.getToUserName() : "")); textView.setText(mqttBean.getFromUserName() != null ? mqttBean.getFromUserName() : ""); tv_time.setText("x" + (mqttBean.getNumber() != null ? mqttBean.getNumber() : "1")); } if (mqttBean.getGift_picture() != null) { ImageUtils.loadHeadCC(mqttBean.getGift_picture(), view.findViewById(com.xscm.moduleutil.R.id.iv_piaoping)); } } else { textView2.setText("送给"); textView.setText(""); tv_time.setText("x1"); } } private void updateXlhFloatingViewData(View view, XLHBean xlhBean) { TextView textView = view.findViewById(R.id.tv_name); ImageView xlh_image = view.findViewById(R.id.im_xlh); if (xlhBean != null) { xlh_image.setImageDrawable(xlhBean.getFrom_type() == 1 ? getResources().getDrawable(com.xscm.moduleutil.R.mipmap.xlh_jjks) : getResources().getDrawable(com.xscm.moduleutil.R.mipmap.xlh_zsks)); textView.setText(xlhBean.getText()); } else { textView.setText(""); } view.setOnClickListener(v -> { // 点击时执行跳转操作 handleItemClick(xlhBean); }); } private void handleItemClick(XLHBean xlhBean) { // 这里可以根据实际需求实现跳转逻辑 // 例如:跳转到礼物详情页面、用户主页等 // 使用缓存数据进入房间 if (ActivityUtils.getTopActivity() instanceof RoomActivity) { if (!Objects.equals(((RoomActivity) ActivityUtils.getTopActivity()).getRoomId(), xlhBean.getRoom_id())) { ((RoomActivity) ActivityUtils.getTopActivity()).refreshRoomInfo(xlhBean.getRoom_id()); } return; } RoomManager.getInstance().fetchRoomDataAndEnter(getApplicationContext(), xlhBean.getRoom_id(), "", null); } private void handleRedItemClick(RedBean redBean) { // 这里可以根据实际需求实现跳转逻辑 // 例如:跳转到礼物详情页面、用户主页等 // 使用缓存数据进入房间 if (ActivityUtils.getTopActivity() instanceof RoomActivity) { if (!Objects.equals(((RoomActivity) ActivityUtils.getTopActivity()).getRoomId(), redBean.getRoom_id())) { ((RoomActivity) ActivityUtils.getTopActivity()).refreshRoomInfo(redBean.getRoom_id()); } return; } RoomManager.getInstance().fetchRoomDataAndEnter(getApplicationContext(), redBean.getRoom_id(), "", null); } // @Subscribe(threadMode = ThreadMode.MAIN) // public void onEvent(ChatInfo event) { // if(ActivityUtils.getTopActivity() instanceof WebViewActivity){ // return; // } // String id = event.getId().replace("g", ""); // Intent intent = new Intent(this, WebViewActivity.class); // intent.putExtra("url", String.format(WebUrlConstants.INSTANCE.getWEB_SET_GROUP_URL(), SpUtil.getToken(), id)); // startActivity(intent); // } public void singleTaskToActivity(Class clazz) { Intent intent = new Intent(this, clazz); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); startActivity(intent); } public void toActivity(Class clazz, Bundle bundle) { Intent intent = new Intent(this, clazz); intent.putExtras(bundle); startActivity(intent); } public void toActivity(Class clazz) { Intent intent = new Intent(this, clazz); startActivity(intent); } }