优化头像框加载、麦圈加载,二卡八放到对应fragment加载。

This commit is contained in:
2026-01-07 16:53:36 +08:00
parent b76136b604
commit d1cd2aeef7
12 changed files with 199 additions and 831 deletions

View File

@@ -31,7 +31,7 @@ public enum QXRoomSeatViewType {
/**
* 酒吧
*/
PUB(7,"酒吧"),
PUB(11,"酒吧"),
/**
* 酒吧
*/

View File

@@ -15,7 +15,7 @@ enum class RoomType(
DATING("交友", 1,3, 4, 8), // 1、3、4、8 均对应交友
BLACK_ROOM("小黑屋", 6),
JUKEBOX("点唱", 9),
PUB_ROOM("酒吧", 7),
PUB_ROOM("酒吧", 11),
PRIVATE_ROOM("酒吧交友小屋", 12),
MUTUAL_ENTERTAINMENT("互娱", 7),
SIGN_CONTRACT("签约", 10);

View File

@@ -107,7 +107,7 @@ public class AgoraManager {
private static List<Music> musicList;
private static boolean isBjMusic = false;
private static List<SoundLevelUpdateListener> soundLevelUpdateListeners = new CopyOnWriteArrayList<>();
private List<SoundLevelUpdateListener> soundLevelUpdateListeners = new CopyOnWriteArrayList<>();
private static ChannelMediaOptions options;
private static RtcConnection connection;
private String pkRoomId = "";
@@ -130,8 +130,6 @@ public class AgoraManager {
private final Handler uiHandler = new Handler(Looper.getMainLooper());
private long lastDispatchTime = 0;
// 缓存本次声网回调的音量结果
private final Map<String, Integer> volumeCache = new HashMap<>();
public void setLastRoomId(String value) {
lastRoomId = value;
}
@@ -212,7 +210,7 @@ public class AgoraManager {
try {
rtcEngine.setAudioProfile(Constants.AUDIO_PROFILE_MUSIC_HIGH_QUALITY_STEREO,
Constants.AUDIO_SCENARIO_GAME_STREAMING);
rtcEngine.enableAudioVolumeIndication(100, 3, false);
rtcEngine.enableAudioVolumeIndication(200, 3, true);
rtcEngine.setClientRole(Constants.CLIENT_ROLE_BROADCASTER);
rtcEngine.muteLocalAudioStream(true); // 默认静音
rtcEngine.muteAllRemoteAudioStreams(false); // 监听远端的音频
@@ -584,6 +582,7 @@ public class AgoraManager {
if (soundLevelUpdateListeners.isEmpty()) return;
for (Map.Entry<String, Integer> entry : volumeSnapshot.entrySet()) {
for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) {
if (listener != null) {
listener.onRemoteSoundLevelUpdate(entry.getKey(), entry.getValue());

View File

@@ -1,13 +1,11 @@
package com.xscm.moduleutil.widget;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SoundEffectConstants;
import android.view.View;
import android.widget.FrameLayout;
@@ -16,21 +14,14 @@ import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import com.blankj.utilcode.util.LogUtils;
import com.liulishuo.okdownload.DownloadTask;
import com.liulishuo.okdownload.core.cause.EndCause;
import com.liulishuo.okdownload.core.cause.ResumeFailedCause;
import com.liulishuo.okdownload.core.listener.DownloadListener1;
import com.liulishuo.okdownload.core.listener.assist.Listener1Assist;
import com.opensource.svgaplayer.SVGACallback;
import com.opensource.svgaplayer.SVGADrawable;
import com.opensource.svgaplayer.SVGADynamicEntity;
import com.opensource.svgaplayer.SVGAImageView;
import com.opensource.svgaplayer.SVGAParser;
import com.opensource.svgaplayer.SVGAVideoEntity;
import com.tencent.qgame.animplayer.inter.IAnimListener;
import com.xscm.moduleutil.R;
import com.xscm.moduleutil.databinding.RoomViewSvgaAnimBinding;
import com.xscm.moduleutil.utils.SpUtil;
import com.xscm.moduleutil.utils.logger.Logger;
import java.io.File;
@@ -40,11 +31,8 @@ import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -57,9 +45,9 @@ import okhttp3.ResponseBody;
public class AvatarFrameView extends FrameLayout {
private PlaybackManager playbackManager;
private boolean isMute = false;
public void setMute(boolean b) {
this.isMute = b;
}
@@ -68,10 +56,7 @@ public class AvatarFrameView extends FrameLayout {
private RenderType renderType;
private SVGAImageView svgaSurface;
private SVGAImageView svgaSurface2;
private final Handler mainHandler = new Handler(Looper.getMainLooper());
private int mType;//1:循环播放 2:播放一次停止播放
private final BlockingQueue<PlayItem> playQueue = new LinkedBlockingQueue<>();
private boolean isPlaying = false;
// 添加销毁标记
@@ -79,8 +64,6 @@ public class AvatarFrameView extends FrameLayout {
private static final String TAG = "AvatarFrameView";
private RoomViewSvgaAnimBinding mBinding;
// 内存监控
private static final long MAX_MEMORY_THRESHOLD = 300 * 1024 * 1024; // 300MB
private static final int MAX_SVGA_CACHE_SIZE = 3;
private final Map<String, WeakReference<SVGAVideoEntity>> svgaCache = new LruCache<>(MAX_SVGA_CACHE_SIZE);
@@ -101,25 +84,10 @@ public class AvatarFrameView extends FrameLayout {
}
private void initViews() {
// if (isDestroyed) return;
// 初始化 ExoPlayer View
// playerView = new PlayerView(getContext());
// playerView.setUseController(false);
// playerView.setVisibility(View.GONE);
// addView(playerView);
// 初始化 SVGA View
svgaSurface = new SVGAImageView(getContext());
svgaSurface.setVisibility(View.GONE);
addView(svgaSurface);
svgaSurface2 = new SVGAImageView(getContext());
svgaSurface2.setVisibility(View.GONE);
addView(svgaSurface2);
// 初始化播放管理器
playbackManager = new PlaybackManager(mainHandler);
}
private String getFileExtension(String url) {
@@ -130,186 +98,51 @@ public class AvatarFrameView extends FrameLayout {
}
return "";
}
public void playNextFromQueue() {
// if (isDestroyed) return;
// 确保在主线程中执行
// if (Looper.myLooper() != Looper.getMainLooper()) {
// mainHandler.post(this::playNextFromQueue);
// return;
// }
// 检查特效是否开启
// if (SpUtil.getOpenEffect() != 1) {
// clearQueue();
// return;
// }
// 检查是否可以开始新的播放
// if (!playbackManager.canStartNewPlayback()) {
// Logger.d("AvatarFrameView", "Max concurrent playbacks reached, waiting...");
// return;
// }
if (!isPlaying || !isActuallyPlaying()) {
PlayItem item = playQueue.poll();
if (item != null) {
// 通知开始播放
playbackManager.onStartPlayback();
isPlaying = true;
// 处理播放项目
processPlayItem(item);
} else {
isPlaying = false;
Logger.d("AvatarFrameView", "Queue is empty, stop playing");
}
}
}
// 添加统一的播放完成处理方法
public void onPlaybackComplete() {
if (isDestroyed) return;
mainHandler.post(() -> {
// 再次检查是否已销毁
if (isDestroyed) return;
// // 通知播放管理器播放完成
// playbackManager.onFinishPlayback();
// 重置播放状态
isPlaying = false;
// 内存清理检查
// if (playQueue.size() % 5 == 0) {
// performLightMemoryCleanup();
// }
// 继续处理队列中的下一个项目
playNextFromQueue();
});
public void setSource(String url, int type2) {
// 添加到播放队列
PlayItem item = new PlayItem(url, type2);
processPlayItem(item);
Logger.d("AvatarFrameView", "Added to queue, queue size: url: " + url);
}
private void processPlayItem(PlayItem item) {
try {
// clearPrevious();
String ext = getFileExtension(item.url);
if ("svga".equalsIgnoreCase(ext)) {
mainHandler.post(() -> {
renderType = RenderType.SVGA;
mType = item.type;
if (mBinding != null && mBinding.playView != null) {
mBinding.playView.setVisibility(View.GONE);
}
loadSVGA(item.url);
});
renderType = RenderType.SVGA;
mType = item.type;
if (mBinding != null) {
mBinding.playView.setVisibility(View.GONE);
}
loadSVGA(item.url);
} else if ("mp4".equalsIgnoreCase(ext)) {
mainHandler.post(() -> {
renderType = RenderType.MP4;
mType = item.type;
if (mBinding != null && mBinding.playView != null) {
mBinding.playView.setVisibility(View.VISIBLE);
downloadAndPlayMp4(item.url);
}else {
mBinding = DataBindingUtil.inflate(LayoutInflater.from(getContext()), R.layout.room_view_svga_anim, this, true);
mBinding.playView.setVisibility(View.VISIBLE);
downloadAndPlayMp4(item.url);
}
});
} else {
// 不支持的格式,直接完成
handlePlaybackComplete();
renderType = RenderType.MP4;
mType = item.type;
if (mBinding != null) {
mBinding.playView.setVisibility(View.VISIBLE);
downloadAndPlayMp4(item.url);
} else {
mBinding = DataBindingUtil.inflate(LayoutInflater.from(getContext()), R.layout.room_view_svga_anim, this, true);
mBinding.playView.setVisibility(View.VISIBLE);
downloadAndPlayMp4(item.url);
}
}
} catch (Exception e) {
LogUtils.e(TAG, "Error processing play item: " + e.getMessage());
handlePlaybackComplete();
}
}
// 添加实际播放状态检查方法
private boolean isActuallyPlaying() {
if (renderType == RenderType.SVGA && svgaSurface != null) {
return svgaSurface.isAnimating();
} else if (renderType == RenderType.MP4 && mBinding != null) {
// 检查播放器状态
return mBinding.playView.isRunning();
}
return false;
}
public boolean isPlaying() {
if (mBinding != null && mBinding.playView != null) {
if (mBinding != null) {
return mBinding.playView.isRunning();
}
return true;
}
// 在 AvatarFrameView 类中添加以下代码
private static final int MAX_CONCURRENT_PROCESSING = 3; // 同时处理的最大动画数
private static final int PROCESSING_DELAY = 100; // 处理间隔(毫秒)
private int currentProcessingCount = 0;
public void setSource(String url, int type2) {
// if (isDestroyed) return;
// 确保在主线程中执行
if (Looper.myLooper() != Looper.getMainLooper()) {
mainHandler.post(() -> setSource(url, type2));
return;
}
// 添加到播放队列
playQueue.add(new PlayItem(url, type2));
Logger.d("AvatarFrameView", "Added to queue, queue size: " + playQueue.size() + ", url: " + url);
if (type2 == 3 || type2 == 1) {
// playNextFromQueue();
loadSVGA(url);
} else {
// 如果当前没有在播放,则开始播放
if (!isPlaying || !isActuallyPlaying()) {
playNextFromQueue();
}
}
Logger.d("AvatarFrameView", "Added to queue, queue size: " + playQueue.size() + ", url: " + url);
}
private void smartCheckAndStartPlayback() {
// 检查是否可以开始新的播放任务
if (!playQueue.isEmpty() &&
(!isPlaying || !isActuallyPlaying()) &&
currentProcessingCount < MAX_CONCURRENT_PROCESSING) {
currentProcessingCount++;
playNextFromQueue();
}
}
private void checkAndStartPlayback() {
// 如果队列不为空且当前没有在播放,则开始播放
if (!playQueue.isEmpty() && (!isPlaying || !isActuallyPlaying())) {
playNextFromQueue();
}
}
private boolean isMemoryLow() {
Runtime runtime = Runtime.getRuntime();
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
long maxMemory = runtime.maxMemory();
double memoryUsage = (double) usedMemory / maxMemory;
// 内存使用超过80%或绝对使用量超过阈值
return memoryUsage > 0.8 || usedMemory > MAX_MEMORY_THRESHOLD;
}
boolean isTxk = false;
public void downloadAndPlayMp4(String url) {
// 提取文件名
String fileName = url.substring(url.lastIndexOf("/"));
String filePath = getContext().getCacheDir().getAbsolutePath() + fileName;
@@ -330,12 +163,6 @@ public class AvatarFrameView extends FrameLayout {
@Override
public void onFailure(Call call, IOException e) {
LogUtils.e("MP4下载失败: " + e.toString());
mainHandler.post(() -> {
// 检查是否已销毁
if (!isDestroyed) {
onPlaybackComplete();
}
});
}
// 更简单的优化版本
@@ -371,63 +198,36 @@ public class AvatarFrameView extends FrameLayout {
fos.flush();
isTxk = true;
mainHandler.post(() -> {
// 关键在执行UI操作前再次检查是否已销毁
if (downloadedFile.exists()) {
LogUtils.d("@@@@Thread", Thread.currentThread().getName());
playMp4File(downloadedFile); // 使用正确的文件引用
} else {
LogUtils.w(TAG, "View destroyed or file not exist after download");
onPlaybackComplete();
}
});
// 关键在执行UI操作前再次检查是否已销毁
if (downloadedFile.exists()) {
LogUtils.d("@@@@Thread", Thread.currentThread().getName());
playMp4File(downloadedFile); // 使用正确的文件引用
} else {
LogUtils.w(TAG, "View destroyed or file not exist after download");
}
} catch (IOException e) {
LogUtils.e("MP4文件保存失败: " + e.getMessage());
mainHandler.post(() -> {
if (!isDestroyed) {
onPlaybackComplete();
}
});
}
} else {
mainHandler.post(() -> {
if (!isDestroyed) {
onPlaybackComplete();
}
});
}
} catch (Exception e) {
LogUtils.e("MP4文件保存失败: " + e.getMessage());
mainHandler.post(() -> {
if (!isDestroyed) {
onPlaybackComplete();
}
});
}
} else {
LogUtils.e("MP4下载响应失败");
mainHandler.post(() -> {
if (!isDestroyed) {
onPlaybackComplete();
}
});
}
}
});
} else {
isTxk = true;
LogUtils.e("有缓存");
mainHandler.post(() -> {
// 检查是否已销毁
if (file.exists()) {
LogUtils.e("有缓存:"+file.exists()+"===="+file.getAbsolutePath());
playMp4File(file);
} else {
LogUtils.w(TAG, "有缓存2222222222222");
}
});
// 检查是否已销毁
if (file.exists()) {
LogUtils.e("有缓存:" + file.exists() + "====" + file.getAbsolutePath());
playMp4File(file);
} else {
LogUtils.w(TAG, "有缓存2222222222222");
}
}
}
@@ -436,13 +236,11 @@ public class AvatarFrameView extends FrameLayout {
// 双重检查确保组件未被销毁
if (isDestroyed) {
LogUtils.w(TAG, "Attempt to play MP4 file after view destroyed");
onPlaybackComplete();
return;
}
if (mBinding == null || mBinding.playView == null) {
if (mBinding == null) {
LogUtils.w(TAG, "PlayView is null");
onPlaybackComplete();
return;
}
@@ -453,27 +251,23 @@ public class AvatarFrameView extends FrameLayout {
} else {
mBinding.playView.setLoop(1); // 播放一次
}
mBinding.playView.setMute(isMute);
mBinding.playView.setMute(isMute);
// 开始播放前检查视图状态
if (!isDestroyed && mBinding != null && mBinding.playView != null) {
mBinding.playView.startPlay(file);
} else {
LogUtils.w(TAG, "View was destroyed before MP4 playback started");
onPlaybackComplete();
}
} else {
LogUtils.e("播放MP4文件出错: 文件不存在或已损坏");
onPlaybackComplete();
}
} catch (Exception e) {
LogUtils.e("播放MP4文件出错: " + e.getMessage());
onPlaybackComplete();
}
}
private void handleSVGAComplete(SVGAVideoEntity videoItem, String url) {
if (svgaSurface == null) {
onPlaybackComplete();
return;
}
@@ -496,7 +290,6 @@ public class AvatarFrameView extends FrameLayout {
svgaSurface.stopAnimation();
svgaSurface.clearAnimation();
svgaSurface.setImageDrawable(null);
onPlaybackComplete();
}
}
@@ -506,11 +299,8 @@ public class AvatarFrameView extends FrameLayout {
@Override
public void onFinished() {
// if (isDestroyed) return;
if (mType == 1) { // 循环播放
// 继续循环播放
} else {
onPlaybackComplete();
}
}
});
@@ -523,10 +313,6 @@ public class AvatarFrameView extends FrameLayout {
svgaSurface.startAnimation();
} catch (Exception e) {
LogUtils.e(TAG, "Error handling SVGA completion: " + e.getMessage());
// isPlaying = false;
// playNextFromQueue();
handlePlaybackComplete();
}
}
@@ -536,13 +322,8 @@ public class AvatarFrameView extends FrameLayout {
svgaSurface.clearAnimation();
svgaSurface.setImageDrawable(null);
}
if (svgaSurface2 != null) {
svgaSurface2.stopAnimation();
svgaSurface2.clearAnimation();
svgaSurface.setImageDrawable(null);
}
// 增加空值检查
if (mBinding != null && mBinding.playView != null) {
if (mBinding != null) {
mBinding.playView.stopPlay();
}
}
@@ -566,16 +347,7 @@ public class AvatarFrameView extends FrameLayout {
@Override
public void onFinished() {
if (Looper.myLooper() != Looper.getMainLooper()) {
mainHandler.post(() -> {
isPlaying = false;
// 添加延迟确保状态更新
mainHandler.postDelayed(AvatarFrameView.this::playNextFromQueue, 50);
});
} else {
isPlaying = false;
mainHandler.postDelayed(AvatarFrameView.this::playNextFromQueue, 50);
}
isPlaying = false;
}
});
// 设置循环次数
@@ -588,21 +360,16 @@ public class AvatarFrameView extends FrameLayout {
} catch (Exception e) {
LogUtils.e(TAG, "Error playing cached SVGA: " + e.getMessage());
isPlaying = false;
mainHandler.postDelayed(AvatarFrameView.this::playNextFromQueue, 50);
// playNextFromQueue();
}
}
private void loadNewSVGA(String url) {
try {
new SVGAParser(getContext()).parse(new URL(url), new SVGAParser.ParseCompletion() {
@Override
public void onComplete(SVGAVideoEntity videoItem) {
// if (isDestroyed) return;
if (Looper.myLooper() != Looper.getMainLooper()) {
mainHandler.post(() -> handleSVGAComplete(videoItem, url));
handleSVGAComplete(videoItem, url);
} else {
handleSVGAComplete(videoItem, url);
}
@@ -610,32 +377,16 @@ public class AvatarFrameView extends FrameLayout {
@Override
public void onError() {
// if (isDestroyed) return;
if (Looper.myLooper() != Looper.getMainLooper()) {
mainHandler.post(() -> {
isPlaying = false;
playNextFromQueue();
});
} else {
isPlaying = false;
playNextFromQueue();
}
isPlaying = false;
}
});
} catch (Exception e) {
LogUtils.e(TAG, "Error parsing SVGA: " + e.getMessage());
isPlaying = false;
playNextFromQueue();
}
}
private void loadSVGA(String url) {
if (Looper.myLooper() != Looper.getMainLooper()) {
mainHandler.post(() -> loadSVGA(url));
return;
}
try {
svgaSurface.setVisibility(View.VISIBLE);
@@ -653,7 +404,6 @@ public class AvatarFrameView extends FrameLayout {
} catch (Exception e) {
LogUtils.e(TAG, "Error loading SVGA: " + e.getMessage());
isPlaying = false;
playNextFromQueue();
}
svgaSurface.setVisibility(View.VISIBLE);
@@ -683,7 +433,6 @@ public class AvatarFrameView extends FrameLayout {
@Override
public void onFinished() {
isPlaying = false;
playNextFromQueue();
}
});
@@ -693,7 +442,6 @@ public class AvatarFrameView extends FrameLayout {
@Override
public void onError() {
isPlaying = false;
playNextFromQueue();
}
});
} catch (Exception e) {
@@ -716,7 +464,6 @@ public class AvatarFrameView extends FrameLayout {
}
// 隐藏所有视图
// if (playerView != null) playerView.setVisibility(View.GONE);
if (svgaSurface != null) svgaSurface.setVisibility(View.GONE);
@@ -750,39 +497,7 @@ public class AvatarFrameView extends FrameLayout {
*/
private void releaseResources() {
LogUtils.d(TAG, "Releasing all resources");
// if (isDestroyed) return;
// 使用异步线程处理耗时操作
new Thread(() -> {
try {
// 在后台线程处理文件操作和大对象清理
// performHeavyCleanup();
// 回到主线程处理 UI 相关的清理
mainHandler.post(() -> {
performUICleanup();
});
} catch (Exception e) {
Logger.e(TAG, "Error in async releaseResources: " + e.getMessage());
// 出错时仍在主线程清理 UI 资源
mainHandler.post(() -> {
performUICleanup();
});
}
}).start();
}
/**
* 在后台线程执行耗时的清理操作
*/
private void performHeavyCleanup() {
try {
// 清理缓存文件(如果需要)
// 清理大对象引用等
// clearCacheFiles();
} catch (Exception e) {
Logger.e(TAG, "Error in performHeavyCleanup: " + e.getMessage());
}
performUICleanup();
}
/**
@@ -791,31 +506,16 @@ public class AvatarFrameView extends FrameLayout {
private void performUICleanup() {
try {
// 停止并清理播放器
if (mBinding != null && mBinding.playView != null) {
if (mBinding != null) {
try {
mBinding.playView.stopPlay();
} catch (Exception e) {
Logger.e(TAG, "Error stopping playView: " + e.getMessage());
}
}
// 清理 ExoPlayer 资源
// if (exoPlayer != null) {
// try {
// // 使用异步停止避免阻塞
// exoPlayer.stop();
// exoPlayer.clearVideoSurface();
// } catch (Exception e) {
// Logger.e(TAG, "Error releasing ExoPlayer resources: " + e.getMessage());
// }
// }
// 清理 SVGA 资源
if (svgaSurface != null) {
try {
// svgaSurface.pauseAnimation();
// svgaSurface.clearAnimation();
// svgaSurface.setImageDrawable(null);
svgaSurface.stopAnimation(true);
svgaSurface.clear();
svgaSurface.clearAnimation();
@@ -834,86 +534,23 @@ public class AvatarFrameView extends FrameLayout {
*/
public void release() {
Logger.d("AvatarFrameView", "Public release called");
// if (isDestroyed) return;
// 确保在主线程中执行
// if (Looper.myLooper() != Looper.getMainLooper()) {
// mainHandler.post(this::release);
// return;
// }
isDestroyed = true;
try {
// 清空播放队列
clearQueue();
// 清理播放管理器
if (playbackManager != null) {
playbackManager.reset();
}
// 释放所有资源
releaseResources();
// 延迟清理其他资源
mainHandler.postDelayed(() -> {
// 清理 binding
if (mBinding != null) {
mBinding = null;
}
}, 100);
// 清理 binding
if (mBinding != null) {
mBinding = null;
}
} catch (Exception e) {
LogUtils.e(TAG, "Error in AvatarFrameView release: " + e.getMessage());
} finally {
// 建议进行垃圾回收
// MemoryOptimizationUtils.forceGC();
}
}
public void clearQueue() {
// if (isDestroyed) return;
playQueue.clear();
isPlaying = false;
// 清理播放管理器中的任务
if (playbackManager != null) {
playbackManager.reset();
}
// 清理当前正在播放的内容
clearPrevious();
}
// 在类成员变量中添加
private static final int PLAYBACK_TIMEOUT = 10000; // 10秒超时
private Map<String, Long> playbackStartTimeMap = new HashMap<>();
// 添加超时检查方法
private void startPlaybackTimeout(String url) {
playbackStartTimeMap.put(url, System.currentTimeMillis());
mainHandler.postDelayed(() -> checkPlaybackTimeout(url), PLAYBACK_TIMEOUT);
}
private void checkPlaybackTimeout(String url) {
Long startTime = playbackStartTimeMap.get(url);
if (startTime != null && System.currentTimeMillis() - startTime > PLAYBACK_TIMEOUT) {
LogUtils.w(TAG, "Playback timeout: " + url);
playbackStartTimeMap.remove(url);
// 强制结束当前播放并继续下一个
handlePlaybackComplete();
}
}
private void cancelPlaybackTimeout(String url) {
playbackStartTimeMap.remove(url);
}
private static class PlayItem {
String url;
int type;
@@ -923,167 +560,4 @@ public class AvatarFrameView extends FrameLayout {
this.type = type;
}
}
/**
* 关闭特效
*/
public void closeEffect() {
// 清空队列
clearQueue();
// 释放资源
// releaseResources();
// 清空队列
// playQueue.clear();
// 关闭动画
// if (mBinding.playView != null && isPlaying && mBinding.playView.isRunning()) {
// mBinding.playView.setAnimation(null);
// mBinding.playView.clearAnimation();
// mBinding.playView.stopPlay();
// }
}
/**
* 开始循环播放SVGA动画
*/
public void startLoopingSvga(String assetName) {
if (Looper.myLooper() != Looper.getMainLooper()) {
mainHandler.post(() -> startLoopingSvga(assetName));
return;
}
try {
// clearPrevious(); // 清除之前的动画
svgaSurface.setVisibility(View.VISIBLE);
new SVGAParser(getContext()).decodeFromAssets(assetName, new SVGAParser.ParseCompletion() {
@Override
public void onComplete(SVGAVideoEntity svgaVideoEntity) {
SVGADrawable drawable = new SVGADrawable(svgaVideoEntity);
svgaSurface.setImageDrawable(drawable);
svgaSurface.setLoops(0); // 0表示无限循环
svgaSurface.startAnimation();
}
@Override
public void onError() {
Log.e(TAG, "解析SVGA文件失败: " + assetName);
}
});
} catch (Exception e) {
Log.e(TAG, "播放SVGA动画出错", e);
}
}
/**
* 停止并销毁当前SVGA动画
*/
public void stopSvga() {
if (Looper.myLooper() != Looper.getMainLooper()) {
mainHandler.post(() -> stopSvga());
return;
}
try {
if (svgaSurface2 != null) {
svgaSurface2.stopAnimation(true);
svgaSurface2.setImageDrawable(null);
svgaSurface2.setVisibility(View.GONE);
}
} catch (Exception e) {
Log.e(TAG, "停止SVGA动画出错", e);
}
}
// 在 AvatarFrameView 类中添加以下代码
// 播放任务管理器
// 替换现有的 PlaybackManager 类
private static class PlaybackManager {
private static final int MAX_CONCURRENT_PLAYBACKS = 3; // 增加并发数
private int currentPlaybackCount = 0;
private final Handler handler;
public PlaybackManager(Handler handler) {
this.handler = handler;
}
public boolean canStartNewPlayback() {
return currentPlaybackCount < MAX_CONCURRENT_PLAYBACKS;
}
public void onStartPlayback() {
currentPlaybackCount++;
}
public void onFinishPlayback() {
currentPlaybackCount = Math.max(0, currentPlaybackCount - 1);
}
public void reset() {
currentPlaybackCount = 0;
}
}
// 播放任务接口
private interface PlaybackTask {
void execute();
}
// 在 AvatarFrameView 类中添加以下代码
// private IAnimListener MP4PlaybackCallback;
// 在 AvatarFrameView 类的成员变量区域添加单例实例
public void setAnimListener(IAnimListener mInstance) {
mBinding.playView.setAnimListener(mInstance);
}
// 添加统一的播放完成处理方法
private void handlePlaybackComplete() {
mainHandler.post(() -> {
if (isDestroyed) return;
isPlaying = false;
// 通知播放管理器任务完成
if (playbackManager != null) {
playbackManager.reset();
}
// 内存检查
if (playQueue.size() % 5 == 0) {
// performLightMemoryCleanup();
}
// 播放下一个
playNextFromQueue();
});
}
// 添加轻量级内存清理方法
private void performLightMemoryCleanup() {
Runtime runtime = Runtime.getRuntime();
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
long maxMemory = runtime.maxMemory();
double memoryUsage = (double) usedMemory / maxMemory;
// 内存使用超过70%时进行清理
if (memoryUsage > 0.7) {
// 清理SVGA缓存
if (svgaCache.size() > 1) {
// 保留最新的缓存项
Iterator<Map.Entry<String, WeakReference<SVGAVideoEntity>>> iterator =
svgaCache.entrySet().iterator();
if (iterator.hasNext()) {
iterator.next(); // 跳过最新的
if (iterator.hasNext()) {
iterator.remove(); // 移除较旧的
}
}
}
// 建议进行垃圾回收
System.gc();
}
}
}

View File

@@ -37,6 +37,7 @@ import com.xscm.moduleutil.event.RoomFaceEvent;
import com.xscm.moduleutil.interfaces.IBaseWheat;
import com.xscm.moduleutil.interfaces.SoundLevelUpdateListener;
import com.xscm.moduleutil.rtc.AgoraManager;
import com.xscm.moduleutil.utils.ImageUtils;
import com.xscm.moduleutil.utils.SpUtil;
import com.xscm.moduleutil.utils.logger.Logger;
@@ -63,6 +64,7 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
public TextView tv_time_pk;
public RoomPitBean pitBean;//麦位数据
public String roomId;//房间id
CountDownTimer mCountDownTimer;
@@ -82,17 +84,14 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
public ImageView iv_on_line;
private boolean showGiftAnim = true;//显示麦位动画
private ImageView iv_tag_type;
// 当前音量监听器,用于防止重复添加
private SoundLevelUpdateListener currentSoundLevelListener;
private TextView tv_zhul;
private SVGAParser mParser;
private final SVGAParser parser = new SVGAParser(CommonAppContext.getInstance());
private String micCycle = "";
public boolean isMentorShip = false;
private SoundLevelUpdateListener soundLevelUpdateListener;
public BaseWheatView(Context context) {
this(context, null, 0);
@@ -112,6 +111,7 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
mIvSex = findViewById(R.id.iv_sex);
mIvFrame = findViewById(R.id.iv_frame);
mIvRipple = findViewById(R.id.iv_ripple);
mIvFace = findViewById(R.id.iv_face);
mIvShutup = findViewById(R.id.iv_shutup);
tvTime = findViewById(R.id.tv_time);
@@ -179,33 +179,61 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
setCardiac(pitBean.getCharm(), getTzbl());
if (bean.getUser_id() != null && !bean.getUser_id().equals("0") && !bean.getUser_id().isEmpty()) {
if (bean.getIs_online()==1){
iv_on_line.setVisibility(GONE);
}else if (bean.getIs_online()==2){
if (!bean.getUser_id().equals(SpUtil.getUserId()+"")) {
iv_on_line.setVisibility(VISIBLE);
}
}else {
iv_on_line.setVisibility(GONE);
}
if (bean.getIs_online() == 1) {
iv_on_line.setVisibility(GONE);
} else if (bean.getIs_online() == 2) {
if (!bean.getUser_id().equals(SpUtil.getUserId() + "")) {
iv_on_line.setVisibility(VISIBLE);
}
} else {
iv_on_line.setVisibility(GONE);
}
} else {
iv_on_line.setVisibility(GONE);
}
if (mParser == null || (!TextUtils.isEmpty(pitBean.getMic_cycle()) && !micCycle.equals(pitBean.getMic_cycle()))) {
LogUtils.e("这是一个很诡异的东西 " + (mParser == null) +",pitBean.getMic_cycle():"+pitBean.getMic_cycle());
if (mParser != null) {
mParser = null;
}
micCycle = pitBean.getMic_cycle();
mParser = new SVGAParser(getContext());
if (TextUtils.isEmpty(pitBean.getMic_cycle())) {
mParser.decodeFromAssets("mic.svga", new SVGAParser.ParseCompletion() {
@Override
public void onComplete(@Nullable SVGAVideoEntity videoItem) {
if (videoItem != null) {
mIvRipple.setVideoItem(videoItem);
}
}
parser.decodeFromAssets("mic.svga", new SVGAParser.ParseCompletion() {
@Override
public void onComplete(@Nullable SVGAVideoEntity videoItem) {
if (videoItem != null) {
mIvRipple.setVideoItem(videoItem);
@Override
public void onError() {
Log.e("SVGA", "解析 ripple.svga 失败");
}
});
} else {
try {
mParser.decodeFromURL(new URL(pitBean.getMic_cycle()),
new SVGAParser.ParseCompletion() {
@Override
public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) {
mIvRipple.setImageDrawable(new SVGADrawable(svgaVideoEntity));
mIvRipple.startAnimation();
}
@Override
public void onError() {
LogUtils.e("BaseWheatView", "解析 mic_cycle 失败");
}
});
} catch (MalformedURLException ignored) {
LogUtils.e("BaseWheatView", "解析 mic_cycle 失败");
}
}
}
@Override
public void onError() {
Log.e("SVGA", "解析 ripple.svga 失败");
}
});
setPitData(bean);
@@ -214,7 +242,7 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
mIvRipple.setScaleX(1.1f);
mIvRipple.setScaleY(1.1f);
}
if (!isMentorShip){
if (!isMentorShip) {
//心动值
//显示心动
@@ -259,13 +287,18 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
}
}
AgoraManager.getInstance().addSoundLevelListener(new SoundLevelUpdateListener() {
if (soundLevelUpdateListener != null){
AgoraManager.getInstance().removeSoundLevelListener(soundLevelUpdateListener);
}
soundLevelUpdateListener = new SoundLevelUpdateListener() {
@Override
public void onRemoteSoundLevelUpdate(String userId, int soundLevel) {
if (mIvRipple == null) return;
if (mIvRipple == null || pitBean.getUser_id().equals("0")) return;
if (!userId.equals(pitBean.getUser_id())) return;
boolean nowSpeaking = soundLevel > 0;
updateSpeakingState(nowSpeaking);
}
@@ -290,9 +323,13 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
if (mIvRipple == null)
return;
mIvRipple.setVisibility(INVISIBLE);
Log.e("SVGA", "-------"+pitBean.getUser_id());
}
}
});
};
AgoraManager.getInstance().addSoundLevelListener(soundLevelUpdateListener);
}
@@ -344,9 +381,11 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
}
@Override
public void onError() {}
public void onError() {
}
});
} catch (MalformedURLException ignored) {}
} catch (MalformedURLException ignored) {
}
}
public void setCharm(String charm) {
@@ -398,13 +437,13 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
public void setOnlineStatus() {
if (pitBean.getUser_id() != null && !pitBean.getUser_id().equals("0") && !pitBean.getUser_id().isEmpty()) {
if (pitBean.getIs_online()==1){
if (pitBean.getIs_online() == 1) {
iv_on_line.setVisibility(GONE);
}else if (pitBean.getIs_online()==2){
if (!pitBean.getUser_id().equals(SpUtil.getUserId()+"")) {
} else if (pitBean.getIs_online() == 2) {
if (!pitBean.getUser_id().equals(SpUtil.getUserId() + "")) {
iv_on_line.setVisibility(VISIBLE);
}
}else {
} else {
iv_on_line.setVisibility(GONE);
}
} else {
@@ -423,6 +462,7 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
showGiftAnim = false;
releaseCountDownTimer();
super.onDetachedFromWindow();
mParser = null;
}
/**
@@ -742,7 +782,6 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
mIvFace.addData(new FaceBean(roomRollModel.getNumber(), 2));
}
/**
* 是否主持
*

View File

@@ -74,7 +74,7 @@ public class RoomKtvWheatView extends BaseWheatView {
sex = bean.getSex();
if (isOn()) {
//开启声浪
if (mCharmView != null) {
if (mIvRipple != null) {
mIvRipple.stopAnimation(true);
mIvRipple.setVisibility(VISIBLE);
}
@@ -103,12 +103,7 @@ public class RoomKtvWheatView extends BaseWheatView {
mIvTagBoss.setVisibility(VISIBLE);
ImageUtils.loadRes(isLocked() ? R.mipmap.room_ic_wheat_default_suo : R.mipmap.room_ic_wheat_default, mRiv);
} else {
// mIvTagBoss.setVisibility(GONE);
// @DrawableRes int origin = getOriginImage();
// ImageUtils.loadRes(isLocked() ? R.mipmap.room_ic_wheat_default_suo :
// (origin == 0 ? R.mipmap.room_ic_wheat_default : origin), mRiv);
mRiv.setImageResource(bean.getIs_lock() == 1 ? R.mipmap.room_ic_wheat_default_suo : R.mipmap.room_ic_wheat_default);
// ImageUtils.loadRes(isLocked() ? R.mipmap.room_ic_wheat_default_suo : R.mipmap.room_ic_wheat_default, mRiv);
}
if (isMute()) {
ImageUtils.loadRes(R.mipmap.room_microphone_off, mIvSex);

View File

@@ -1,169 +0,0 @@
package com.xscm.moduleutil.widget;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.opensource.svgaplayer.SVGAImageView;
import com.xscm.moduleutil.R;
import com.xscm.moduleutil.bean.room.RoomPitBean;
import com.xscm.moduleutil.utils.ImageUtils;
public class RoomSingWheatView extends LinearLayout {
public ImageView mRiv;
public ImageView mIvGift;
public WheatCharmView mCharmView;
public TextView mTvName;
public ImageView mIvSex;
public AvatarFrameView mIvFrame;
public AvatarFrameView mIvRipple;
public ExpressionImgView mIvFace;
public ImageView mIvShutup;
public TextView tvTime;
public TextView mTvNo;
public TextView tv_time_pk;
public RoomPitBean pitBean;//麦位数据
public String roomId;//房间id
public static final String WHEAT_BOSS = "8";//老板位
public static final String WHEAT_HOST = "9";//主持位
public float oX;
public float oY;
boolean closePhone = false;//自己麦位关闭话筒,用于判断声纹显示
public String pitNumber;
public int pitImageVId;
// public ImageView iv_on_line;
private boolean showGiftAnim = true;//显示麦位动画
private ImageView iv_tag_type;
private TextView tv_zhul;
public RoomSingWheatView(@NonNull Context context) {
this(context, null);
}
public RoomSingWheatView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public RoomSingWheatView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
private void initView(Context context) {
// 确保布局被正确加载
inflate(context, getLayoutId(), this);
// 初始化所有视图组件
mRiv = findViewById(R.id.riv);
mIvGift = findViewById(R.id.iv_gift);
mCharmView = findViewById(R.id.charm_view);
mTvName = findViewById(R.id.tv_name);
mIvSex = findViewById(R.id.iv_sex);
mIvFrame = findViewById(R.id.iv_frame);
mIvRipple = findViewById(R.id.iv_ripple);
mIvFace = findViewById(R.id.iv_face);
mIvShutup = findViewById(R.id.iv_shutup);
tvTime = findViewById(R.id.tv_time);
tv_time_pk = findViewById(R.id.tv_time_pk);
mTvNo = findViewById(R.id.tv_no);
// iv_on_line = findViewById(R.id.iv_online);
iv_tag_type = findViewById(R.id.iv_tag_type);
tv_zhul = findViewById(R.id.tv_zhul);
// 设置初始位置
if (mIvGift != null) {
oX = mIvGift.getX();
oY = mIvGift.getY();
}
}
protected int getLayoutId() {
return R.layout.room_view_sing_wheat;
}
public void setData(RoomPitBean bean) {
this.pitBean = bean;
if (bean == null) return;
// 添加空值检查防止NPE
if (mTvName == null) {
// 可能布局未正确加载,尝试重新初始化
initView(getContext());
if (mTvName == null) {
// 如果仍然为null记录日志并返回
android.util.Log.e("RoomSingWheatView", "mTvName is still null after re-initialization");
return;
}
}
if (isOn()) {
//开启声浪
mIvRipple.startLoopingSvga("mic.svga");
mIvRipple.setVisibility(VISIBLE);
mTvName.setText(bean.getNickname());
ImageUtils.loadHeadCC(bean.getAvatar(), mRiv);
if (TextUtils.isEmpty(pitBean.getDress())) {
if (mIvFrame != null) mIvFrame.setVisibility(INVISIBLE);
} else {
if (mIvFrame != null) {
mIvFrame.setVisibility(VISIBLE);
mIvFrame.setSource(pitBean.getDress(), 3);
}
}
} else {
String pitText = "-1".equals(pitNumber) ? "" :
"9".equals(pitNumber) ? "主持位" :
"10".equals(pitNumber) ? "嘉宾位" :
pitNumber + "号麦位";
mTvName.setText(pitText);
if (mIvFrame != null) mIvFrame.setVisibility(INVISIBLE);
if (mIvFace != null) mIvFace.remove();
//停止声浪
mIvRipple.stopSvga();
mIvRipple.setVisibility(GONE);
}
// 更新魅力值视图
if (mCharmView != null) {
if (pitBean.getNickname() == null || pitBean.getNickname().isEmpty()) {
mCharmView.setVisibility(GONE);
} else {
mCharmView.setVisibility(VISIBLE);
}
}
// 更新PK状态
if (tv_time_pk != null) {
if (pitBean.is_pk() && pitBean.getUser_id() != null &&
!pitBean.getUser_id().equals("0") && !pitBean.getUser_id().isEmpty()) {
tv_time_pk.setVisibility(VISIBLE);
if (mCharmView != null) mCharmView.setVisibility(GONE);
} else {
tv_time_pk.setVisibility(GONE);
if (mCharmView != null) mCharmView.setVisibility(VISIBLE);
}
}
}
private boolean isOn() {
return pitBean != null && !TextUtils.isEmpty(pitBean.getUser_id()) && !"0".equals(pitBean.getUser_id());
}
}

View File

@@ -10,18 +10,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- <com.opensource.svgaplayer.SVGAImageView-->
<!-- android:id="@+id/image"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="0dp"-->
<!-- android:scaleType="fitCenter"-->
<!-- app:autoPlay="true"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- app:loopCount="1" />-->
<com.tencent.qgame.animplayer.AnimView
android:id="@+id/play_view"
android:layout_width="0dp"
@@ -29,8 +17,6 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -96,9 +96,7 @@ open class Application : CommonAppContext() {
configureLeakCanary()
// 初始化并预绘制视图 二卡八列
WheatLayoutSingManager.init(this)
WheatLayoutSingManager.getInstance().setWheatData(null)
// 默认情况下SVGA 内部不会输出任何 log所以需要手动设置为 true
SVGALogger.setLogEnabled(false)

View File

@@ -484,26 +484,30 @@ public class RoomAuctionFragment extends BaseMvpFragment<RoomAuctionPresenterTow
private void getTextView() {
int defaultColor = ContextCompat.getColor(requireContext(), com.xscm.moduleutil.R.color.color_0DFFB9); // 亲密拍默认颜色(绿色)
int selectedColor = ContextCompat.getColor(requireContext(), com.xscm.moduleutil.R.color.color_white); // 选中颜色(色)
int clickedColor = ContextCompat.getColor(requireContext(), com.xscm.moduleutil.R.color.color_BB8BE2); // 真爱拍选中颜色(色)
float defaultSize = 16f; // 默认字体大小
float selectedSize = 24f; // 选中字体大小
mBinding.zhenai.setText("真爱拍");
mBinding.qinmi.setText("亲密");
// 根据type设置初始状态
if (type == 1) {
// type=1 真爱拍模式
mBinding.zhenai.setTextColor(clickedColor); // 真爱拍蓝色
mBinding.zhenai.setTextSize(TypedValue.COMPLEX_UNIT_SP, selectedSize); // 真爱拍24号字体
mBinding.qinmi.setTextColor(selectedColor); // 亲密拍白色
mBinding.qinmi.setTextSize(TypedValue.COMPLEX_UNIT_SP, defaultSize); // 亲密拍16号字体
} else {
// type=2 亲密拍模式
mBinding.qinmi.setTextColor(defaultColor); // 亲密拍绿色
mBinding.qinmi.setTextSize(TypedValue.COMPLEX_UNIT_SP, selectedSize); // 亲密拍24号字体
mBinding.zhenai.setTextColor(selectedColor); // 真爱拍白色
mBinding.zhenai.setTextSize(TypedValue.COMPLEX_UNIT_SP, defaultSize); // 真爱拍16号字体
try {
int defaultColor = ContextCompat.getColor(requireContext(), com.xscm.moduleutil.R.color.color_0DFFB9); // 亲密拍默认颜色(绿色)
int selectedColor = ContextCompat.getColor(requireContext(), com.xscm.moduleutil.R.color.color_white); // 选中颜色(色)
int clickedColor = ContextCompat.getColor(requireContext(), com.xscm.moduleutil.R.color.color_BB8BE2); // 真爱拍选中颜色(蓝色)
float defaultSize = 16f; // 默认字体大小
float selectedSize = 24f; // 选中字体大小
mBinding.zhenai.setText("真爱");
mBinding.qinmi.setText("亲密拍");
// 根据type设置初始状态
if (type == 1) {
// type=1 真爱拍模式
mBinding.zhenai.setTextColor(clickedColor); // 真爱拍蓝色
mBinding.zhenai.setTextSize(TypedValue.COMPLEX_UNIT_SP, selectedSize); // 真爱拍24号字体
mBinding.qinmi.setTextColor(selectedColor); // 亲密拍白色
mBinding.qinmi.setTextSize(TypedValue.COMPLEX_UNIT_SP, defaultSize); // 亲密拍16号字体
} else {
// type=2 亲密拍模式
mBinding.qinmi.setTextColor(defaultColor); // 亲密拍绿色
mBinding.qinmi.setTextSize(TypedValue.COMPLEX_UNIT_SP, selectedSize); // 亲密拍24号字体
mBinding.zhenai.setTextColor(selectedColor); // 真爱拍白色
mBinding.zhenai.setTextSize(TypedValue.COMPLEX_UNIT_SP, defaultSize); // 真爱拍16号字体
}
}catch (Exception e){
LogUtils.e("getTextView",e.getMessage());
}
mBinding.zhenai.setOnClickListener(v -> {
if (wheatView.getUserId().equals(SpUtil.getUserId() + "")) {

View File

@@ -449,7 +449,7 @@ public class RoomFragment extends BaseMvpFragment<RoomPresenter, FragmentRoomBin
if (newFragment != null) {
// switchFragment(newFragment, mBinding.roomItem.getId(), false);
performFragmentReplacement(newFragment);
performFragmentReplacementReplace(newFragment);
} else {
LogUtils.e("newFragment==null");
}
@@ -474,6 +474,47 @@ public class RoomFragment extends BaseMvpFragment<RoomPresenter, FragmentRoomBin
}
private Fragment currentFragment = null;
@SuppressLint("CheckResult")
private void performFragmentReplacementReplace(Fragment newFragment) {
if (getActivity() != null && getActivity() instanceof RoomActivity) {
if (newFragment instanceof RoomKtvFragment) {
Objects.requireNonNull(((RoomActivity) getActivity()).getBinding()).recyclerView.setVisibility(View.VISIBLE);
} else {
Objects.requireNonNull(((RoomActivity) getActivity()).getBinding()).recyclerView.setVisibility(View.GONE);
}
}
if (getChildFragmentManager().isDestroyed()) {
return; // 避免状态销毁后操作导致崩溃
}
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
// 动画(可选,不想动画可以删掉)
transaction.setCustomAnimations(
com.xscm.moduleutil.R.anim.a_slide_right_in,
com.xscm.moduleutil.R.anim.a_slide_left_out
);
// 使用 replace 替换当前 fragment
transaction.replace(mBinding.roomItem.getId(), newFragment, newFragment.getClass().getSimpleName());
// 如果需要保留回退栈可用 addToBackStack
// transaction.addToBackStack(newFragment.getClass().getSimpleName());
transaction.commitAllowingStateLoss();
// 更新当前 fragment 引用
currentFragment = newFragment;
// 延迟启动透明 Activity保持原逻辑
Observable.timer(1000, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> {
if (ActivityUtils.getTopActivity() instanceof RoomActivity)
startActivity(new Intent(ActivityUtils.getTopActivity(), TransparentActivity.class));
});
}
@SuppressLint("CheckResult")
private void performFragmentReplacement(Fragment newFragment) {
@@ -730,7 +771,6 @@ public class RoomFragment extends BaseMvpFragment<RoomPresenter, FragmentRoomBin
}
if (getActivity() instanceof RoomActivity) {
RoomActivity roomActivity = (RoomActivity) getActivity();
if (!haveMe) {
AgoraManager.getInstance().ClientRole(false);
AgoraManager.getInstance().setLocalAudioEnabled(false, SpUtil.getUserId() + "");

View File

@@ -94,13 +94,10 @@ public class SingSongFragment extends BaseRoomFragment<SingSongPresenter, Fragme
protected String pitNumber;//当前点击的麦序
protected CommonDialog commonDialog;
// private WheatLayoutManager wheatLayoutManager;
private final WheatLayoutSingManager wheatLayoutSingManager = WheatLayoutSingManager.Companion.getInstance();
private WheatLayoutSingManager wheatLayoutSingManager = null;
private WheatLayoutManager wheatLayoutManager1;
private WheatLayoutManager wheatLayoutManager2;
private RoomPitBean roomPitBean;
private PopupWindow popupWindow;
CountDownTimer mCountDownTimer;
CountDownTimer mCountDownTimersta;
@@ -148,6 +145,11 @@ public class SingSongFragment extends BaseRoomFragment<SingSongPresenter, Fragme
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// initPopupWindow(); 2025年12月24日11:18:58去掉弹框直接进行抱麦
// 初始化并预绘制视图 二卡八列
WheatLayoutSingManager.Companion.init(getActivity());
WheatLayoutSingManager.Companion.getInstance().setWheatData(null);
wheatLayoutSingManager = WheatLayoutSingManager.Companion.getInstance();
flexboxLayout = mBinding.flexboxLayout;
var wheatContainer = WheatLayoutSingManager.Companion.getInstance().getRootContainer();
flexboxLayout.addView(wheatContainer);