Files
midi-android/moduleUtil/src/main/java/com/xscm/moduleutil/activity/BaseAppCompatActivity.java
2025-10-17 10:04:43 +08:00

1222 lines
46 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.xscm.moduleutil.activity;
import static androidx.core.content.ContextCompat.getSystemService;
import static com.xscm.moduleutil.base.CommonAppContext.postDelayed;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
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.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import com.alibaba.android.arouter.launcher.ARouter;
import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.BarUtils;
import com.blankj.utilcode.util.LogUtils;
import com.hjq.toast.ToastUtils;
import com.tencent.qcloud.tuikit.tuichat.bean.ChatInfo;
import com.xscm.moduleutil.R;
import com.xscm.moduleutil.base.CommonAppContext;
import com.xscm.moduleutil.base.RoomManager;
import com.xscm.moduleutil.bean.XLHBean;
import com.xscm.moduleutil.event.HourlyBean;
import com.xscm.moduleutil.event.MqttBean;
import com.xscm.moduleutil.event.RedBean;
import com.xscm.moduleutil.utils.ARouteConstants;
import com.xscm.moduleutil.utils.BackgroundManager;
import com.xscm.moduleutil.utils.ColorManager;
import com.xscm.moduleutil.utils.DisplayUtil;
import com.xscm.moduleutil.utils.ImageUtils;
import com.xscm.moduleutil.utils.SpUtil;
import com.xscm.moduleutil.utils.SystemUtils;
import com.xscm.moduleutil.widget.QXGiftDriftView;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends AppCompatActivity
implements BackgroundManager.BackgroundUpdateListener, ColorManager.ColorChangeListener {
@Override
protected void attachBaseContext(Context newBase) {
// 设置字体缩放比例为1.0f,即不跟随系统字体大小变化
super.attachBaseContext(DisplayUtil.attachBaseContext(newBase, 1.0f));
}
protected VDB mBinding;
private static final List<BaseMvpActivity> activityList = new ArrayList<>();
// private LoadingDialog mLoadingDialog;
// 添加广播接收器成员变量
private BroadcastReceiver mLogoutReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if ("com.xscm.moduleutil.ACTION_USER_LOGOUT".equals(intent.getAction())) {
// 在这里处理用户登出后的UI更新
// 例如:隐藏需要登录才能显示的控件
// 或者跳转到登录状态的页面
handleUserLogout();
}
}
};
// 处理用户登出的方法
protected void handleUserLogout() {
// 子类可以重写此方法处理具体的登出逻辑
// 例如更新UI状态、清除本地数据等
ActivityUtils.finishAllActivities();
}
QXGiftDriftView qxGiftDriftView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().getDecorView().setBackgroundResource(R.mipmap.log_bj);
setContentView(getLayoutId());
// 隐藏标题栏
if (getSupportActionBar() != null) {
getSupportActionBar().hide();
}
mBinding = DataBindingUtil.setContentView(this, getLayoutId());
mBinding.setLifecycleOwner(this);
ARouter.getInstance().inject(this);
BarUtils.setStatusBarLightMode(this, isLightMode());
BarUtils.transparentStatusBar(this);
initView();
initData();
initCompleted();
// 注册背景更新监听器
BackgroundManager.getInstance().addListener(this);
// 尝试加载网络背景
loadNetworkBackground();
// 注册颜色变化监听器
ColorManager.getInstance().addColorChangeListener(this);
// 注册登出广播接收器
IntentFilter filter = new IntentFilter("com.xscm.moduleutil.ACTION_USER_LOGOUT");
registerReceiver(mLogoutReceiver, filter);
// 动态判断是否包含 @Subscribe 注解的方法
boolean hasSubscribeMethods = false;
for (Method method : getClass().getDeclaredMethods()) {
if (method.isAnnotationPresent(Subscribe.class)) {
hasSubscribeMethods = true;
break;
}
}
if (hasSubscribeMethods) {
EventBus.getDefault().register(this);
}
// 启动定时器
// startTimer();
}
// 在Activity中
private static final int REQUEST_OVERLAY_PERMISSION = 1001;
private void checkAndRequestOverlayPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
new AlertDialog.Builder(this)
.setTitle("需要悬浮窗权限")
.setMessage("应用需要悬浮窗权限才能显示飘屏效果")
.setPositiveButton("去设置", (dialog, which) -> {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_OVERLAY_PERMISSION);
})
.setNegativeButton("取消", null)
.show();
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_OVERLAY_PERMISSION) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.canDrawOverlays(this)) {
ToastUtils.show("已获得悬浮窗权限");
} else {
ToastUtils.show("未获得悬浮窗权限");
}
}
}
}
public static void finishAll() {
for (BaseMvpActivity activity : activityList) {
if (!activity.isFinishing()) {
activity.finish();
}
}
}
@Override
public void onColorChanged() {
// 在主线程中更新UI
runOnUiThread(this::updateUIColors);
}
// 子类可以重写此方法来更新UI颜色
protected void updateUIColors() {
// 默认实现,子类可以覆盖
}
//在类中添加以下成员变量
private Handler timerHandler = new Handler();
private Runnable timerRunnable = new Runnable() {
@Override
public void run() {
// 调用你要执行的方法
// executePeriodicTask();
// 每10秒执行一次
timerHandler.postDelayed(this, 10000);
}
};
// 启动定时器的方法
private void startTimer() {
timerHandler.postDelayed(timerRunnable, 10000);
}
// 你需要定期执行的方法
private void executePeriodicTask() {
// 在这里实现你的业务逻辑
LogUtils.d("定时任务执行中...");
List<HourlyBean> hourlyBeans = new ArrayList<>();
HourlyBean hourlyBean = new HourlyBean();
hourlyBean.setText("nihao");
hourlyBean.setRank_number("1");
hourlyBean.setRoom_name("夏末");
hourlyBean.setRoom_id("1");
hourlyBeans.add(hourlyBean);
onMessageReceived(hourlyBeans);
}
protected void loadNetworkBackground() {
// 只有当已经有背景URL时才加载
String backgroundUrl = BackgroundManager.getInstance().getBackgroundUrl();
if (backgroundUrl != null && !backgroundUrl.isEmpty()) {
// 检查是否有已加载的drawable
Drawable cachedDrawable = BackgroundManager.getInstance().getBackgroundDrawable();
if (cachedDrawable != null) {
getWindow().getDecorView().setBackground(cachedDrawable);
} else {
// 加载网络背景
BackgroundManager.getInstance().loadBackgroundDrawable(this, new BackgroundManager.BackgroundLoadCallback() {
@Override
public void onLoadSuccess(Drawable drawable) {
getWindow().getDecorView().setBackground(drawable);
}
@Override
public void onLoadFailed() {
// 加载失败时使用默认背景
getWindow().getDecorView().setBackgroundResource(R.mipmap.activity_bj);
}
});
}
}
}
@Override
public void onBackgroundUpdated(Drawable drawable) {
// 当背景更新时更新当前Activity的背景
if (drawable != null) {
getWindow().getDecorView().setBackground(drawable);
}
}
// 提供一个方法供子类调用用于设置背景URL
protected void setNetworkBackgroundUrl(String url) {
BackgroundManager.getInstance().setBackgroundUrl(url);
}
@Override
public Resources getResources() {//禁止app字体大小跟随系统字体大小调节
Resources resources = super.getResources();
if (resources != null && resources.getConfiguration().fontScale != 1.0f) {
android.content.res.Configuration configuration = resources.getConfiguration();
configuration.fontScale = 1.0f;
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
}
return resources;
}
static float fontScale = 1f;
// @Override
// public Resources getResources() {
// Resources resources = super.getResources();
// return DisplayUtil.getResources(this,resources,fontScale);
// }
public void setFontScale(float fontScale) {
this.fontScale = fontScale;
DisplayUtil.recreate(this);
}
public boolean isLightMode() {
return true;
}
protected abstract void initData();
protected abstract void initView();
protected void initCompleted() {
}
protected abstract int getLayoutId();
@Override
protected void onDestroy() {
// 清理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);
}
// 移除背景更新监听器
BackgroundManager.getInstance().removeListener(this);
// 移除颜色变化监听器
ColorManager.getInstance().removeColorChangeListener(this);
if (mBinding != null) {
mBinding.unbind();
}
if (EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().unregister(this);
}
try {
unregisterReceiver(mLogoutReceiver);
} catch (Exception e) {
// 忽略异常
}
try {
unregisterReceiver(mLogoutReceiver);
} catch (Exception e) {
// 忽略异常
}
super.onDestroy();
}
public void showLoading(String content) {
// if (mLoadingDialog == null) {
// mLoadingDialog = new LoadingDialog(this);
// }
// if (!mLoadingDialog.isShowing()) {
// mLoadingDialog.show();
// }
}
public void showLoading() {
// if (mLoadingDialog == null) {
// mLoadingDialog = new LoadingDialog(this);
// }
// if (!mLoadingDialog.isShowing()) {
// mLoadingDialog.show();
// }
}
public void disLoading() {
// if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
// mLoadingDialog.dismiss();
// }
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
View view = getCurrentFocus();
if (isShouldHideInput(view, ev)) {
InputMethodManager Object = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (Object != null) {
Object.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
}
try {
return super.dispatchTouchEvent(ev);
} catch (Exception e) {
return false;
}
}
//判断是否隐藏键盘
public boolean isShouldHideInput(View v, MotionEvent event) {
if (v != null && (v instanceof EditText)) {
int[] leftTop = {0, 0};
//获取输入框当前的location位置
v.getLocationInWindow(leftTop);
int left = leftTop[0];
int top = leftTop[1];
int bottom = top + v.getHeight();
int right = left + v.getWidth();
if (event.getX() > left && event.getX() < right
&& event.getY() > top && event.getY() < bottom) {
// 点击的是输入框区域保留点击EditText的事件
return false;
} else {
return true;
}
}
return false;
}
/// 礼物特效
// 在类中添加以下成员变量
private final List<MqttBean.ListBean> mqttMessageQueue = new ArrayList<>(); // MQTT消息队列
private final List<XLHBean> xlhMessageQueue = new ArrayList<>(); // XLH消息队列
private final List<RedBean> 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<HourlyBean> hourlyMessageQueue = new ArrayList<>(); // 小时榜消息队列
private final Map<Integer, View> currentHourlyViews = new HashMap<>(); // 当前显示的小时榜视图
private final Object hourlyQueueLock = new Object(); // 小时榜队列同步锁
private boolean isHourlyProcessing = false; // 小时榜处理状态标志
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageReceived(List<HourlyBean> 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<HourlyBean> 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(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(R.id.tv_name);
ImageView ivAvatar = view.findViewById(R.id.im_h_t);
if (hourlyBean != null) {
// 根据排名设置不同的显示
switch (hourlyBean.getRank_number()) {
case "1":
// tvName.setText("新科状元! ["+hourlyBean.getRoom_name()+"] 独占鳌头!");
setColoredText(tvName, "新科状元! [", hourlyBean.getRoom_name(), "] 独占鳌头!", R.color.color_FFFA63);
ivAvatar.setImageResource(R.mipmap.hourl_top1);
break;
case "2":
// tvName.setText("金榜榜眼! ["+hourlyBean.getRoom_name()+"] 才气逼人!");
setColoredText(tvName, "金榜榜眼! [", hourlyBean.getRoom_name(), "] 才气逼人!", R.color.color_FFFA63);
ivAvatar.setImageResource(R.mipmap.hourl_top2);
break;
case "3":
setColoredText(tvName, "风采探花! [", hourlyBean.getRoom_name(), "] 实力绽放!", R.color.color_1FFFE5);
// tvName.setText("风采探花! ["+hourlyBean.getRoom_name()+"] 实力绽放!");
ivAvatar.setImageResource(R.mipmap.hourl_top3);
break;
default:
tvName.setVisibility(View.GONE);
ivAvatar.setVisibility(View.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 (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(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);
// 播放红包音效
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, 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);
}
}
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, 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, 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(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(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.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(2000);
exitAnim.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
// 移除视图并处理下一个
// ViewGroup rootView = (ViewGroup) getParent();
// if (rootView != null) {
// rootView.removeView(QXGiftDriftView.this);
// }
//
// if (!dataArray.isEmpty()) {
// dataArray.remove(0);
// }
// isPlaying = false;
//
// if (!dataArray.isEmpty()) {
// giftAction();
// }
onAnimationEnd.run();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
view.startAnimation(exitAnim);
}, 3000); // 停留1秒
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
view.startAnimation(enterAnim);
// ObjectAnimator animator1 = ObjectAnimator.ofFloat(view, "translationX", view.getWidth(), 0f);
// animator1.setDuration(1500);
// animator1.setInterpolator(new DecelerateInterpolator(1f));
// animator1.start();
// view.postDelayed(() -> {
// try {
// ObjectAnimator animator2 = ObjectAnimator.ofFloat(view, "translationX", 0f, -view.getWidth());
// animator2.setDuration(3000);
// 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("MQTT动画执行失败", e);
// onAnimationEnd.run();
// }
// }, 3000);
} 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(R.id.tv_name);
TextView textView2 = view.findViewById(R.id.tv_to_name);
TextView tv_time = view.findViewById(R.id.tv_num);
if (mqttBean != null) {
textView2.setText("送给" + (mqttBean.getToUserName() != null ? mqttBean.getToUserName() : ""));
textView.setText(mqttBean.getFromUserName() != null ? mqttBean.getFromUserName() : "");
if (mqttBean.getGift_picture() != null) {
ImageUtils.loadHeadCC(mqttBean.getGift_picture(), view.findViewById(R.id.iv_piaoping));
}
tv_time.setText("x" + (mqttBean.getNumber() != null ? mqttBean.getNumber() : "1"));
} 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(R.mipmap.xlh_jjks) :
getResources().getDrawable(R.mipmap.xlh_zsks));
textView.setText(xlhBean.getText());
} else {
textView.setText("");
}
view.setOnClickListener(v -> {
// 点击时执行跳转操作
handleItemClick(xlhBean);
});
}
private void handleItemClick(XLHBean xlhBean) {
// 这里可以根据实际需求实现跳转逻辑
// 例如:跳转到礼物详情页面、用户主页等
// 使用缓存数据进入房间
RoomManager.getInstance().fetchRoomDataAndEnter(getApplicationContext(), xlhBean.getRoom_id(), "");
// ARouter.getInstance().build(ARouteConstants.ROOM_DETAILS).withString("from", "我的界面").withString("roomId", xlhBean.getRoom_id()).navigation();
}
private void handleRedItemClick(RedBean redBean) {
// 这里可以根据实际需求实现跳转逻辑
// 例如:跳转到礼物详情页面、用户主页等
// 使用缓存数据进入房间
RoomManager.getInstance().fetchRoomDataAndEnter(getApplicationContext(), redBean.getRoom_id(), "");
// ARouter.getInstance().build(ARouteConstants.ROOM_DETAILS).withString("from", "我的界面").withString("roomId", xlhBean.getRoom_id()).navigation();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(ChatInfo event) {
String id = event.getId().replace("g", "");
Intent intent = new Intent(this, WebViewActivity.class);
intent.putExtra("url", CommonAppContext.getInstance().getCurrentEnvironment().getH5Url() + "/web/index.html#/pages/union/setGroup?id=" + SpUtil.getToken() + "&guildId=" + id);
startActivity(intent);
// ARouter.getInstance().build(ARouteConstants.H5).withString("url", CommonAppContext.getInstance().getCurrentEnvironment().getH5Url() + "/web/index.html#/pages/union/setGroup?id=" + SpUtil.getToken() + "&guildId=" + id).navigation();
}
}