diff --git a/app/src/main/java/com/qxcm/qxlive/AppContext.java b/app/src/main/java/com/qxcm/qxlive/AppContext.java index b6e8f669..b50647a4 100644 --- a/app/src/main/java/com/qxcm/qxlive/AppContext.java +++ b/app/src/main/java/com/qxcm/qxlive/AppContext.java @@ -2,14 +2,14 @@ package com.qxcm.qxlive; import com.alibaba.android.arouter.launcher.ARouter; import com.hjq.toast.ToastUtils; -import com.xscm.moduleutil.base.CommonAppContext; +import com.xscm.modulemain.Application; /** * Created by cxf on 2017/8/3. */ -public class AppContext extends CommonAppContext { +public class AppContext extends Application { private boolean mBeautyInited; diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/BaseEvent.java b/moduleUtil/src/main/java/com/xscm/moduleutil/BaseEvent.java index 0be483f2..8b71a188 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/BaseEvent.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/BaseEvent.java @@ -1,7 +1,9 @@ package com.xscm.moduleutil; import lombok.Data; +import lombok.EqualsAndHashCode; +@EqualsAndHashCode(callSuper = false) @Data public class BaseEvent { } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/event/RedBean.java b/moduleUtil/src/main/java/com/xscm/moduleutil/event/RedBean.java index 481cadbc..bbc5979c 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/event/RedBean.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/event/RedBean.java @@ -3,9 +3,11 @@ package com.xscm.moduleutil.event; import com.xscm.moduleutil.BaseEvent; import lombok.Data; +import lombok.EqualsAndHashCode; import java.io.Serializable; +@EqualsAndHashCode(callSuper = true) @Data public class RedBean extends BaseEvent implements Serializable { private static final long serialVersionUID = 1L; diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/event/RoomOwnerLeaveEvent.java b/moduleUtil/src/main/java/com/xscm/moduleutil/event/RoomOwnerLeaveEvent.java index 53bf6650..6ef823d7 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/event/RoomOwnerLeaveEvent.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/event/RoomOwnerLeaveEvent.java @@ -3,7 +3,9 @@ package com.xscm.moduleutil.event; import com.xscm.moduleutil.BaseEvent; import lombok.Data; +import lombok.EqualsAndHashCode; +@EqualsAndHashCode(callSuper = true) @Data public class RoomOwnerLeaveEvent extends BaseEvent { private String room_id; diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/event/RoomWheatEvent.java b/moduleUtil/src/main/java/com/xscm/moduleutil/event/RoomWheatEvent.java index 56265670..942c8215 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/event/RoomWheatEvent.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/event/RoomWheatEvent.java @@ -4,8 +4,10 @@ import com.xscm.moduleutil.BaseEvent; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +@EqualsAndHashCode(callSuper = true) @Data @AllArgsConstructor @NoArgsConstructor diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/event/SurfaceEvent.java b/moduleUtil/src/main/java/com/xscm/moduleutil/event/SurfaceEvent.java index 37a52431..4b0bf95f 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/event/SurfaceEvent.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/event/SurfaceEvent.java @@ -12,7 +12,7 @@ import lombok.Data; * @Description 判断是否是电影房$ */ @Data -public class SurfaceEvent extends BaseEvent { +public class SurfaceEvent extends BaseEvent { private SurfaceView surfaceView; private int type; diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/rtc/AgoraManager.java b/moduleUtil/src/main/java/com/xscm/moduleutil/rtc/AgoraManager.java index d946711d..c38135a8 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/rtc/AgoraManager.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/rtc/AgoraManager.java @@ -362,46 +362,6 @@ public class AgoraManager { // 填入用于鉴权的 Token contentCenterConfiguration.token = SpUtil.getRtmToken(); -// 创建 IAgoraMusicContentCenterEventHandler,用于 SDK 向客户端发送音乐内容中心事件通知 -// contentCenterConfiguration.eventHandler = new IMusicContentCenterEventHandler() { -// @Override -// public void onPreLoadEvent(String requestId, long songCode, int percent, String lyricUrl, int status, int errorCode) { -// LogUtils.e("@@@1", "requestId: " + requestId + ", songCode: " + songCode + ", percent: " + percent + ", lyricUrl: " + lyricUrl + ", status: " + status + ", errorCode: " + errorCode); -// if (!lyricUrl.isEmpty() && percent == 100 && !isBjMusic) { -// getLyricsInstance(lyricUrl); -// } -//// musicPlayer.open(songCode, 0); -// } -// -// @Override -// public void onMusicCollectionResult(String requestId, int page, int pageSize, int total, Music[] list, int errorCode) { -// LogUtils.e("@@@2", "requestId: " + requestId + ", page: " + page + ", pageSize: " + pageSize + ", total: " + total); -// MusicBean musicBean = new MusicBean(); -// musicBean.setMusicList(Arrays.asList(list)); -// musicBean.setPage(page); -// EventBus.getDefault().post(musicBean); -// } -// -// @Override -// public void onMusicChartsResult(String requestId, MusicChartInfo[] list, int errorCode) { -// LogUtils.e("@@@", "requestId: " + requestId); -// } -// -// @Override -// public void onLyricResult(String requestId, long songCode, String lyricUrl, int errorCode) { -// LogUtils.e("@@@22", "requestId: " + requestId + ", songCode: " + songCode + ", lyricUrl: " + lyricUrl + ", errorCode: " + errorCode); -// if (lyricUrl != null && !isBjMusic) { -// getLyricsInstance(lyricUrl); -// } -// } -// -// @Override -// public void onSongSimpleInfoResult(String requestId, long songCode, String simpleInfo, int errorCode) { -// LogUtils.e("@@@", "requestId: " + requestId + ", songCode: " + songCode + ", simpleInfo: " + simpleInfo + ", errorCode: " + errorCode); -// } -// }; -// 初始化 IAgoraMusicContentCenter - musicContentCenter.initialize(contentCenterConfiguration); if (musicPlayer != null) { musicPlayer = null; @@ -413,15 +373,8 @@ public class AgoraManager { if (state == 0) { musicPlayer.stop(); musicPlayer.open(songCode, 0); -// getLyricsInstance(lyricUrl); } LogUtils.e("AgoraManager", "isPreload2: " + songCode, "percent: " + percent); - -// if (!lyricUrl.isEmpty() && percent == 100 && !isBjMusic) { -// musicPlayer.stop(); -// musicPlayer.open(songCode, 0); -//// getLyricsInstance(lyricUrl); -// } } @Override @@ -473,19 +426,12 @@ public class AgoraManager { @Override public void onUserJoined(int uid, int elapsed) {//远端用户加入频道 -// for (IRtcEngineEventHandler handler : eventHandlers) { -// if (handler != null) { -// handler.onUserJoined(uid, elapsed); -// -// } -// } for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) { if (listener != null) { ThreadUtils.runOnUiThread(() -> { // 远程用户音量变化 listener.userJoined(uid, elapsed); -// } }); } } @@ -500,19 +446,13 @@ public class AgoraManager { @Override public void onUserOffline(int uid, int reason) {//远端用户离开频道 -// for (IRtcEngineEventHandler handler : eventHandlers) { -// if (handler != null) { -// handler.onUserOffline(uid, reason); -// } for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) { if (listener != null) { ThreadUtils.runOnUiThread(() -> { // 远程用户音量变化 listener.userOffline(uid, reason); -// } }); } -// } } SurfaceView renderView = null; rtcEngine.setupRemoteVideo(new VideoCanvas(null, Constants.RENDER_MODE_FIT, uid)); @@ -535,7 +475,6 @@ public class AgoraManager { ThreadUtils.runOnUiThread(() -> { // 远程用户音量变化 listener.onRemoteSoundLevelUpdate(uid > 0 ? String.valueOf(uid) : SpUtil.getUserId() + "", volume); -// } }); } } @@ -705,39 +644,8 @@ public class AgoraManager { } } - public void joinChannelEx(String token, String channelId, int uid,String pkUserIds) { - if (rtcEngine == null) { - init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId()); - } - if (rtcEngine != null) { - options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER; - options.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING; - options.publishMicrophoneTrack = true; // 是否发布麦克风音频 - options.enableAudioRecordingOrPlayout = true; - options.autoSubscribeAudio = true; - connection = new RtcConnection(); - connection.channelId = channelId; - connection.localUid = SpUtil.getUserId(); - pkRoomId = channelId; - pkUserId = Integer.parseInt(pkUserIds); -// rtcEngine.joinChannelEx(token, connection, options, getDefaultEventHandler()); -// muteAllRemoteAudioStreamsEx(true); -// muteAllRemoteAudioStreamsExUserId(false); - - } - } - - public void leaveChannelEx(String mRoomId, int uid) { - if (rtcEngine != null) { - RtcConnection connection = new RtcConnection(); - connection.channelId = mRoomId; - connection.localUid = uid; -// rtcEngine.leaveChannelEx(connection); - } - } public void updateChannelMediaOptions() { - if (rtcEngine != null) { options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER; // options.autoSubscribeVideo = true; @@ -757,30 +665,8 @@ public class AgoraManager { public void post() { if (rtcEngine != null) { -// rtcEngine.setParameters("{\"che.video.mobile_1080p\":true}"); -// rtcEngine.setClientRole(Constants.CLIENT_ROLE_BROADCASTER); -// -// /*Enable video module*/ -// rtcEngine.enableVideo(); -// // Setup video encoding configs -// rtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration( -// VD_640x360, -// FRAME_RATE_FPS_15, -// STANDARD_BITRATE, -// ORIENTATION_MODE_ADAPTIVE -// )); -// /*Set up to play remote sound with receiver*/ -// rtcEngine.setDefaultAudioRoutetoSpeakerphone(true); ScreenCaptureParameters screenCaptureParameters = new ScreenCaptureParameters(); -// screenCaptureParameters.captureVideo = true; -// screenCaptureParameters.videoCaptureParameters.width = 1440; -// screenCaptureParameters.videoCaptureParameters.height = 1940; -// screenCaptureParameters.videoCaptureParameters.framerate = 15; -// screenCaptureParameters.captureAudio = true; -// screenCaptureParameters.audioCaptureParameters.captureSignalVolume = 50; -//// screenCaptureParameters.videoCaptureParameters.bitrate = 500; -// rtcEngine.startScreenCapture(screenCaptureParameters); WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = manager.getDefaultDisplay(); @@ -807,26 +693,6 @@ public class AgoraManager { } - public void setExternalMediaProjection(MediaProjection[] mediaProjection){ - rtcEngine.setExternalMediaProjection(mediaProjection[0]); - } - - public void isPost(){ - if (rtcEngine != null){ - ScreenCaptureParameters screenCaptureParameters = new ScreenCaptureParameters(); - -// 设置新的屏幕共享参数 - screenCaptureParameters.captureVideo = true; - screenCaptureParameters.videoCaptureParameters.width = 1280; - screenCaptureParameters.videoCaptureParameters.height = 720; - screenCaptureParameters.videoCaptureParameters.framerate = 30; - -// 更新屏幕共享参数 - rtcEngine.updateScreenCaptureParameters(screenCaptureParameters); - - } - } - public void isMute(int index) { if (rtcEngine != null) { } @@ -838,13 +704,6 @@ public class AgoraManager { } } - public void stopMusicPlayer() { - if (musicPlayer != null) { - musicPlayer.stop(); - } - } - - /** * 完全销毁实例(只在应用退出时调用) */ @@ -967,23 +826,6 @@ public class AgoraManager { return isLocalAudioEnabled; } - /** - * 添加事件监听器(用于全局回调) - */ -// public void addEventHandler(IRtcEngineEventHandler handler) { -// if (handler != null && !eventHandlers.contains(handler)) { -// eventHandlers.add(handler); -// } -// } - - /** - * 移除事件监听器 - */ -// public void removeEventHandler(IRtcEngineEventHandler handler) { -// if (handler != null) { -// eventHandlers.remove(handler); -// } -// } public void addSoundLevelListener(SoundLevelUpdateListener listener) { if (soundLevelUpdateListeners != null) { soundLevelUpdateListeners.add(listener); @@ -996,6 +838,12 @@ public class AgoraManager { } } + public void removeAllSoundLevelListener() { + if (soundLevelUpdateListeners != null) { + soundLevelUpdateListeners.clear(); + } + } + public void searchMusic(String keyword, int page) { if (musicContentCenter == null) { musicContentCenter = IAgoraMusicContentCenter.create(rtcEngine); diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/rtc/AgoraManagerEx.java b/moduleUtil/src/main/java/com/xscm/moduleutil/rtc/AgoraManagerEx.java index 5b8254e7..0d767dbe 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/rtc/AgoraManagerEx.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/rtc/AgoraManagerEx.java @@ -300,9 +300,6 @@ public class AgoraManagerEx { }; } public void joinChannelEx(String token, String channelId, String pkUserIds) { -// if (rtcEngineEx == null) { -// init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId()); -// }00602f7339ec98947deaeab173599891932IAAe1VwQOurJj57ZCxEJ3SO8VCK6MPKfAjdo5v/oOHPd5BTK+bCVBxwwIgDobHEAn5cDaQQAAQCflwNpAwCflwNpAgCflwNpBACflwNp if (rtcEngineEx != null) { options = new ChannelMediaOptions(); options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER; @@ -327,12 +324,6 @@ public class AgoraManagerEx { init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId()); } if (rtcEngineEx != null) { -// RtcConnection connection = new RtcConnection(); -// connection.channelId = mRoomId; -// if (connection == null) { -// connection = new RtcConnection(); -// connection.channelId = pkRoomId; -// } rtcEngineEx.muteAllRemoteAudioStreamsEx(enabled, connection); } } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AvatarFrameView.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AvatarFrameView.java index ea46383e..e1263edd 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AvatarFrameView.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AvatarFrameView.java @@ -57,72 +57,13 @@ import okhttp3.ResponseBody; public class AvatarFrameView extends FrameLayout { private PlaybackManager playbackManager; - - private void handleVideoComplete() { -// if (isDestroyed) return; - - if (mType == 1) { - if (mBinding != null && mFile != null) { - mBinding.playView.startPlay(mFile); // 循环播放 - } - } else { - isPlaying = false; -// playNextFromQueue(); // 播放下一项 - currentProcessingCount = Math.max(0, currentProcessingCount - 1); - - // 内存检查和清理 - if (playQueue.size() % 1 == 0) { // 每处理10个动画检查一次内存 - performLightCleanup(); - } - - // 延迟处理下一个,避免过于频繁 - mainHandler.postDelayed(() -> { - smartCheckAndStartPlayback(); - }, PROCESSING_DELAY); -// mainHandler.postDelayed(this::playNextFromQueue, 50); - } - } - - private void performLightCleanup() { - // 只清理不需要的缓存,保留正在使用的资源 - 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) { - // 保留最近使用的1个缓存项 - String oldestKey = null; - for (String key : svgaCache.keySet()) { - if (oldestKey == null) { - oldestKey = key; - } - } - if (oldestKey != null) { - svgaCache.remove(oldestKey); - } - } - - // 建议进行垃圾回收 - System.gc(); - } - } - public enum RenderType {SVGA, MP4} private RenderType renderType; - // private ExoPlayer exoPlayer; -// private PlayerView playerView; private SVGAImageView svgaSurface; private SVGAImageView svgaSurface2; - private GLSurfaceView glSurfaceView; private final Handler mainHandler = new Handler(Looper.getMainLooper()); - private ChannelSplitRenderer1 renderer; private int mType;//1:循环播放 2:播放一次停止播放 - private File mFile; private final BlockingQueue playQueue = new LinkedBlockingQueue<>(); private boolean isPlaying = false; @@ -369,55 +310,7 @@ public class AvatarFrameView extends FrameLayout { playNextFromQueue(); } } - - // 异步处理URL解析等耗时操作 -// ThreadUtils.executeByIo(new ThreadUtils.SimpleTask() { -// @Override -// public String doInBackground() throws Throwable { -// // 在后台线程进行URL有效性检查或其他预处理 -// if (url == null || url.isEmpty()) { -// return null; -// } -// return url; // 返回处理后的URL -// } -// -// @Override -// public void onSuccess(String processedUrl) { -// if (processedUrl != null) { -// // 使用post方法确保在下一个UI循环中执行 -// mainHandler.post(() -> { -// // 再次检查状态 -// if (!isDestroyed && !isPlaying) { -// playQueue.add(new PlayItem(processedUrl, type2)); -//// checkAndStartPlayback(); -// // 智能检查并开始播放 -// smartCheckAndStartPlayback(); -// } else { -// // 如果正在播放,添加到队列中 -// playQueue.add(new PlayItem(processedUrl, type2)); -// } -// }); -// } -// } -// -// @Override -// public void onFail(Throwable e) { -// LogUtils.e("Error processing gift URL: " + e.getMessage()); -// } -// }); - // 添加到播放队列 -// playQueue.offer(new PlayItem(url, type2)); -// playQueue.add(new PlayItem(url, type2)); Logger.d("AvatarFrameView", "Added to queue, queue size: " + playQueue.size() + ", url: " + url); - - // 如果当前没有在播放,则开始播放 -// if (!isPlaying) { -// playNextFromQueue(); -// } - // 改进播放检查逻辑 -// checkAndStartPlayback(); - - } private void smartCheckAndStartPlayback() { @@ -568,14 +461,8 @@ public class AvatarFrameView extends FrameLayout { playMp4File(file); } else { LogUtils.w(TAG, "有缓存2222222222222"); -// onPlaybackComplete(); } }); - // 直接播放缓存文件 -// if (isTxk) { -// mBinding.playView.setLoop(1); -// } -// mBinding.playView.startPlay(file); } } @@ -619,138 +506,6 @@ public class AvatarFrameView extends FrameLayout { } } - // private void downloadAndPlayMp4(String url) { -// String filePath = PathUtils.getInternalAppCachePath() + Md5Utils.getStringMD5(url) + ".mp4"; -// File file = new File(filePath); -// -// if (file.exists() && file.length() > 0) { -// playMp4(file); -// mFile = file; -// } else { -// // 删除可能存在的损坏文件 -//// if (file.exists()) { -//// file.delete(); -//// } -// -// DownloadTask task = new DownloadTask.Builder(url, PathUtils.getInternalAppCachePath() -// , Md5Utils.getStringMD5(url) + ".mp4") -// .setMinIntervalMillisCallbackProcess(300) -// .setPassIfAlreadyCompleted(true) -// .setAutoCallbackToUIThread(true) -// .setConnectionCount(3) // 增加连接数提高稳定性 -// .setReadBufferSize(1024 * 8) // 增大缓冲区 -// .build(); -// if (StatusUtil.isCompleted(task)) { -// playMp4(task.getFile()); -// mFile = task.getFile(); -// } else if (StatusUtil.isSameTaskPendingOrRunning(task)) { -// Logger.d(TAG, "Task is pending or running, checking if it's stuck"); -// // 检查任务是否可能卡住了 -// // 添加超时机制,如果任务长时间没有进展,则重新开始 -// checkAndHandleStuckTask(task, url); -// } else { -// Logger.d(TAG, "Starting new download task"); -// startNewDownload(task, url); -// } -// -//// else if (StatusUtil.isSameTaskPendingOrRunning(task)) { -//// // 如果任务正在进行中,等待完成 -//// // 可以通过监听器处理 -//// attachToExistingTask(task); -//// } else { -//// task.enqueue(new DownloadListener1() { -//// @Override -//// public void taskStart(@NonNull DownloadTask task, @NonNull Listener1Assist.Listener1Model model) { -//// Logger.e("AvatarFrameView1", model); -//// } -//// -//// @Override -//// public void retry(@NonNull DownloadTask task, @NonNull ResumeFailedCause cause) { -//// Logger.e("AvatarFrameView2", cause); -//// -//// } -//// -//// @Override -//// public void connected(@NonNull DownloadTask task, int blockCount, long currentOffset, long totalLength) { -//// Logger.e("AvatarFrameView3", blockCount); -//// } -//// -//// @Override -//// public void progress(@NonNull DownloadTask task, long currentOffset, long totalLength) { -//// Logger.e("AvatarFrameView4", currentOffset); -//// } -//// -//// @Override -//// public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause, @NonNull Listener1Assist.Listener1Model model) { -//// Logger.e("AvatarFrameView5", model); -////// playMp4(task.getFile()); -////// mFile = task.getFile(); -////// if (cause != null && cause != EndCause.COMPLETED) { -//////// CrashReport.postCatchedException(new RuntimeException("下载任务结束:" + cause == null ? "" : cause.name() + "_realCause:" + realCause == null ? "" : realCause.getMessage())); -////// } -//// -//// if (cause == EndCause.COMPLETED) { -//// File downloadedFile = task.getFile(); -//// if (downloadedFile != null && downloadedFile.exists() && downloadedFile.length() > 0) { -//// playMp4(downloadedFile); -//// mFile = downloadedFile; -//// } else { -//// Logger.e(TAG, "Downloaded file is invalid"); -//// handleDownloadFailure(url, cause, new IOException("Downloaded file is invalid")); -//// } -//// } else { -//// handleDownloadFailure(url, cause, realCause); -//// } -//// } -//// }); -//// } -// } -// } - // 添加检查进行中任务的方法 - private void attachToExistingTask(DownloadTask task) { - // 为已经在队列中的任务附加监听器 - task.enqueue(new DownloadListener1() { - @Override - public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause, @NonNull Listener1Assist.Listener1Model model) { - if (cause == EndCause.COMPLETED) { - playMp4(task.getFile()); - mFile = task.getFile(); - } else { - isPlaying = false; - playNextFromQueue(); - } - } - - // 其他回调方法保持空实现或按需处理 - @Override - public void taskStart(@NonNull DownloadTask task, @NonNull Listener1Assist.Listener1Model model) { - } - - @Override - public void retry(@NonNull DownloadTask task, @NonNull ResumeFailedCause cause) { - } - - @Override - public void connected(@NonNull DownloadTask task, int blockCount, long currentOffset, long totalLength) { - } - - @Override - public void progress(@NonNull DownloadTask task, long currentOffset, long totalLength) { - } - }); - } - - private void playMp4(File file) { - if (file != null) { - mBinding.playView.startPlay(file); - - } else { -// showAnim(); -// playMp4(file); -// CrashReport.postCatchedException(new RuntimeException("播放MP4失败:File is null")); - } - } - private void handleSVGAComplete(SVGAVideoEntity videoItem, String url) { if (svgaSurface == null) { onPlaybackComplete(); @@ -758,7 +513,6 @@ public class AvatarFrameView extends FrameLayout { } try { - // 缓存实体(使用弱引用) // 缓存实体(使用弱引用) if (svgaCache.size() < MAX_SVGA_CACHE_SIZE) { svgaCache.put(url, new WeakReference<>(videoItem)); @@ -793,15 +547,6 @@ public class AvatarFrameView extends FrameLayout { } else { onPlaybackComplete(); } -// if (Looper.myLooper() != Looper.getMainLooper()) { -// mainHandler.post(() -> { -// isPlaying = false; -// playNextFromQueue(); -// }); -// } else { -// isPlaying = false; -// playNextFromQueue(); -// } } }); // 设置循环次数 @@ -838,8 +583,6 @@ public class AvatarFrameView extends FrameLayout { } private void playCachedSVGA(SVGAVideoEntity videoItem) { -// if (isDestroyed || svgaSurface == null) return; - try { SVGADrawable drawable = new SVGADrawable(videoItem, new SVGADynamicEntity()); svgaSurface.setImageDrawable(drawable); @@ -858,18 +601,14 @@ public class AvatarFrameView extends FrameLayout { @Override public void onFinished() { -// if (isDestroyed) return; - if (Looper.myLooper() != Looper.getMainLooper()) { mainHandler.post(() -> { isPlaying = false; // 添加延迟确保状态更新 mainHandler.postDelayed(AvatarFrameView.this::playNextFromQueue, 50); -// playNextFromQueue(); }); } else { isPlaying = false; -// playNextFromQueue(); mainHandler.postDelayed(AvatarFrameView.this::playNextFromQueue, 50); } } @@ -890,7 +629,6 @@ public class AvatarFrameView extends FrameLayout { } private void loadNewSVGA(String url) { -// if (isDestroyed) return; try { new SVGAParser(getContext()).parse(new URL(url), new SVGAParser.ParseCompletion() { @@ -928,8 +666,6 @@ public class AvatarFrameView extends FrameLayout { } private void loadSVGA(String url) { -// if (isDestroyed || svgaSurface == null) return; - if (Looper.myLooper() != Looper.getMainLooper()) { mainHandler.post(() -> loadSVGA(url)); return; @@ -986,13 +722,6 @@ public class AvatarFrameView extends FrameLayout { } }); -// svgaSurface.setCallback(new SVGAImageViewCallback() { -// @Override -// public void onAnimationFinished() { -// isPlaying = false; -// playNextFromQueue(); -// } -// }); svgaSurface.startAnimation(); } @@ -1007,65 +736,9 @@ public class AvatarFrameView extends FrameLayout { } } -// private void loadMP4(String url) { -// svgaSurface.setVisibility(View.GONE); -// playerView.setVisibility(View.GONE); -// -// glSurfaceView.setVisibility(View.VISIBLE); -// glSurfaceView.onResume(); -// glSurfaceView.requestRender(); -// // 使用 post 确保 GLSurfaceView 已完成 layout -// glSurfaceView.post(() -> { -// Log.d("@@@", "GLSurfaceView size after layout: " + glSurfaceView.getWidth() + "x" + glSurfaceView.getHeight()); -// -// glSurfaceView.onResume(); -// glSurfaceView.requestRender(); -// -// renderer.setOnSurfaceTextureReadyListener(surfaceTexture -> { -// mainHandler.post(() -> { -// Surface surface = new Surface(surfaceTexture); -// -// MediaItem mediaItem = MediaItem.fromUri(Uri.parse(url)); -// exoPlayer.setMediaItem(mediaItem); -// exoPlayer.setVideoSurface(surface); -// exoPlayer.prepare(); -// exoPlayer.play(); -// Log.d("@@@", "ExoPlayer state after play: " + exoPlayer.getPlaybackState()); -// }); -// }); -// }); -// } private void clearPrevious() { - // 确保在主线程中执行 -// if (Looper.myLooper() != Looper.getMainLooper()) { -// mainHandler.post(() -> { -// clearPrevious(); -//// } -// }); -// return; -// } try { - // 停止并清理 ExoPlayer -// if (exoPlayer != null) { -// try { -// exoPlayer.stop(); // 这里可能会在错误线程中调用 -// exoPlayer.clearVideoSurface(); -// } catch (Exception e) { -// Logger.e("Error stopping ExoPlayer: " + e.getMessage()); -// // 如果在错误线程中,切换到主线程重试 -// mainHandler.post(() -> { -// try { -// if (exoPlayer != null) { -// exoPlayer.stop(); -// exoPlayer.clearVideoSurface(); -// } -// } catch (Exception ex) { -// Logger.e("Error stopping ExoPlayer on main thread: " + ex.getMessage()); -// } -// }); -// } -// } // 停止并清理 SVGA 动画 if (svgaSurface != null && svgaSurface.getDrawable() instanceof SVGADrawable) { SVGADrawable drawable = (SVGADrawable) svgaSurface.getDrawable(); @@ -1090,15 +763,6 @@ public class AvatarFrameView extends FrameLayout { } catch (Exception e) { LogUtils.e(TAG, "Error in clearPrevious: " + e.getMessage()); } - -// if (svgaSurface.getDrawable() instanceof SVGADrawable) { -// ((SVGADrawable) svgaSurface.getDrawable()).stop(); -// } - -// if (playerView != null) playerView.setVisibility(View.GONE); -// if (svgaSurface != null) svgaSurface.setVisibility(View.GONE); -// if (glSurfaceView != null) glSurfaceView.setVisibility(View.GONE); -// mBinding.playView.setVisibility(View.GONE); } // 简单的 LRU Cache 实现 @@ -1141,40 +805,6 @@ public class AvatarFrameView extends FrameLayout { }); } }).start(); - - -// try { -// // 清理 SVGA 资源 -// if (svgaSurface != null && svgaSurface.getDrawable() instanceof SVGADrawable) { -// SVGADrawable drawable = (SVGADrawable) svgaSurface.getDrawable(); -// if (drawable != null) { -// try { -// drawable.stop(); -// svgaSurface.clearAnimation(); -// svgaSurface.setImageDrawable(null); -// } catch (Exception e) { -// LogUtils.e(TAG, "Error releasing SVGA resources: " + e.getMessage()); -// } -// } -// } -// -// // 停止并清理播放器 -// if (mBinding != null && mBinding.playView != null) { -// mBinding.playView.stopPlay(); -// } -// -// // 清理 ExoPlayer 资源 -// if (exoPlayer != null) { -// try { -// exoPlayer.stop(); -// exoPlayer.clearVideoSurface(); -// } catch (Exception e) { -// LogUtils.e(TAG, "Error releasing ExoPlayer resources: " + e.getMessage()); -// } -// } -// } catch (Exception e) { -// LogUtils.e(TAG, "Error in releaseResources: " + e.getMessage()); -// } } /** diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java index 841b5add..0e70881e 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java @@ -4,14 +4,19 @@ import android.content.Context; import android.os.CountDownTimer; import android.text.TextUtils; import android.util.AttributeSet; +import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.DrawableRes; +import androidx.annotation.Nullable; import androidx.constraintlayout.widget.ConstraintLayout; +import com.blankj.utilcode.util.LogUtils; import com.opensource.svgaplayer.SVGAImageView; +import com.opensource.svgaplayer.SVGAParser; +import com.opensource.svgaplayer.SVGAVideoEntity; import com.xscm.moduleutil.R; import com.xscm.moduleutil.base.CommonAppContext; import com.xscm.moduleutil.base.RoomRollModel; @@ -75,6 +80,9 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe private TextView tv_zhul; + private SVGAParser parser = new SVGAParser(getContext()); + + public BaseWheatView(Context context) { this(context, null, 0); } @@ -100,7 +108,7 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe 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); + tv_zhul = findViewById(R.id.tv_zhul); setClipChildren(false); setClipToPadding(false); oX = mIvGift.getX(); @@ -141,15 +149,12 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe } - - /** * 设置麦位数据 * * @param bean */ - @Override - @Subscribe(threadMode = ThreadMode.MAIN) + public void setData(RoomPitBean bean) { if (!pitNumber.equals(bean.getPit_number())) { return; @@ -160,42 +165,33 @@ 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 (CommonAppContext.getInstance().getOnlineMap()!=null&&CommonAppContext.getInstance().getOnlineMap().get(bean.getUser_id())!=null) { + if (bean.getUser_id() != null && !bean.getUser_id().equals("0") && !bean.getUser_id().isEmpty()) { + if (CommonAppContext.getInstance().getOnlineMap() != null && CommonAppContext.getInstance().getOnlineMap().get(bean.getUser_id()) != null) { iv_on_line.setVisibility(CommonAppContext.getInstance().getOnlineMap().get(bean.getUser_id()) == 1 ? GONE : VISIBLE); - }else { + } else { iv_on_line.setVisibility(GONE); } - }else { + } else { iv_on_line.setVisibility(GONE); } + + parser.decodeFromAssets("ripple3695.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 失败"); + } + }); + setPitData(bean); -// if (bean.getIs_online() == 2 && bean.getUser_id()!=null && !bean.getUser_id().equals("0") && !bean.getUser_id().isEmpty()){ -// iv_on_line.setVisibility(VISIBLE); -// }else { -// iv_on_line.setVisibility(GONE); -// } -// if (bean.getIs_online() == 0 &&bean.getUser_id() != null && !bean.getUser_id().equals("0") && !bean.getUser_id().isEmpty()) { -// iv_on_line.setVisibility(VISIBLE); -// } else { -// iv_on_line.setVisibility(GONE); -// } -// if (isOn() && bean.getBall_state() == 1) { -// gameImgView.startGame(); -// } else { -// gameImgView.overGame(); -// } -// String userOnlineStatusBean = SpUtil.getUserOnline(); -// if (userOnlineStatusBean!= null){ -//// if (userOnlineStatusBean.getUser_id().equals(bean.getUser_id()) && userOnlineStatusBean.getIs_online() == 1){ -//// iv_on_line.setVisibility(GONE); -//// }else { -//// iv_on_line.setVisibility(VISIBLE); -//// } -// } //心动值 //显示心动 if ("1".equals(pitBean.getShutup())) { @@ -205,15 +201,10 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe } //自动调节麦位波纹 -// if (!TextUtils.isEmpty(bean.getDress_picture())) { - if (mIvRipple!= null) { + if (mIvRipple != null) { mIvRipple.setScaleX(1.1f); mIvRipple.setScaleY(1.1f); } -// } else { -// mIvRipple.setScaleX(0.9f); -// mIvRipple.setScaleY(0.9f); -// } if (pitNumber.equals("9")) { iv_tag_type.setImageResource(R.mipmap.zc); if (mRiv.getLayoutParams() instanceof ConstraintLayout.LayoutParams) { @@ -250,29 +241,21 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe AgoraManager.getInstance(getContext()).addSoundLevelListener(new SoundLevelUpdateListener() { @Override public void onRemoteSoundLevelUpdate(String userId, int soundLevel) { - if (mIvRipple == null) + if (mIvRipple == null) return; + if (userId.equals(pitBean.getUser_id())) { if (soundLevel == 0) { - mIvRipple.post(() -> { - mIvRipple.stopAnimation(true); - CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(),1); - mIvRipple.setVisibility(INVISIBLE); - }); + mIvRipple.pauseAnimation(); + CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(), 1); mIvRipple.setVisibility(INVISIBLE); } else { mIvRipple.setVisibility(VISIBLE); - mIvRipple.post(() -> { - if (!mIvRipple.isAnimating()) { - mIvRipple.startAnimation(); - CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(),1); - iv_on_line.setVisibility(GONE); - } - - }); + mIvRipple.startAnimation(); + CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(), 1); + iv_on_line.setVisibility(GONE); } } - } @Override @@ -280,50 +263,32 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe if (mIvRipple == null) return; if (volume == 0) { - mIvRipple.post(() -> { - mIvRipple.setVisibility(GONE); - }); + mIvRipple.setVisibility(GONE); } else { mIvRipple.setVisibility(VISIBLE); - mIvRipple.post(() -> { - if (!mIvRipple.isAnimating()) { - mIvRipple.startAnimation(); - CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(),1); - iv_on_line.setVisibility(GONE); - } - - }); - } - } - - @Override - public void userJoined(int userId, int elapsd) { - if (pitBean != null && pitBean.getUser_id() != null && !pitBean.getUser_id().equals("0")) { - if (pitBean.getUser_id().equals(userId + "")) { -// iv_on_line.setVisibility(GONE); + if (!mIvRipple.isAnimating()) { + mIvRipple.startAnimation(); + CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(), 1); + iv_on_line.setVisibility(GONE); } } } + @Override + public void userJoined(int userId, int elapsd) { + + } + @Override public void userOffline(int userId, int reason) { -// if (pitBean != null && pitBean.getUser_id() != null && !pitBean.getUser_id().equals("0")) { -// if (pitBean.getUser_id().equals(userId + "")) { -//// iv_on_line.setVisibility(VISIBLE); -// } -// }else if (pitBean.getUser_id()==null || pitBean.getUser_id().equals("0") || pitBean.getUser_id().equals("")){ -//// iv_on_line.setVisibility(GONE); -// } + } }); - if (pitBean.getUser_id()==null || pitBean.getUser_id().equals("0") || pitBean.getUser_id().equals("") ){ -// iv_on_line.setVisibility(GONE); - } } - public void setCharm(String charm){ + public void setCharm(String charm) { mCharmView.setSex(pitBean.getSex(), pitBean.getUser_id(), charm, false); } @@ -370,27 +335,14 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe } } -// @Subscribe(threadMode = ThreadMode.MAIN) public void setOnlineStatus() { -// if (pitBean!=null) { -// if (pitBean.getUser_id() != null && !pitBean.getUser_id().equals("0") && !pitBean.getUser_id().isEmpty()) { -// if (pitBean.getUser_id().equals(isOnline.getUser_id())) { -// if (isOnline.getIs_online() == 1) { -// iv_on_line.setVisibility(GONE); -// } else { -// iv_on_line.setVisibility(VISIBLE); -// } -// } -// } -// } - - if (pitBean.getUser_id()!=null && !pitBean.getUser_id().equals("0") && !pitBean.getUser_id().isEmpty()) { - if (CommonAppContext.getInstance().getOnlineMap()!=null&&CommonAppContext.getInstance().getOnlineMap().get(pitBean.getUser_id())!=null) { + if (pitBean.getUser_id() != null && !pitBean.getUser_id().equals("0") && !pitBean.getUser_id().isEmpty()) { + if (CommonAppContext.getInstance().getOnlineMap() != null && CommonAppContext.getInstance().getOnlineMap().get(pitBean.getUser_id()) != null) { iv_on_line.setVisibility(CommonAppContext.getInstance().getOnlineMap().get(pitBean.getUser_id()) == 1 ? GONE : VISIBLE); - }else { + } else { iv_on_line.setVisibility(GONE); } - }else { + } else { iv_on_line.setVisibility(GONE); } } @@ -445,7 +397,6 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe if (listBean.getUser_id() == null || !listBean.getUser_id().equals(pitBean.getUser_id())) { return; } -// ImageUtils.loadImageView(listBean.getPicture(), mIvGift); WheatGiftAnim.addGift(mIvGift, listBean.getPicture()); } @@ -459,7 +410,6 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe if (mCharmView != null) { pitBean.setCharm((rough_number != null && !rough_number.isEmpty()) ? rough_number : "0"); if (pitBean.getUser_id() == null || pitBean.getUser_id().equals("0") || pitBean.getUser_id().equals("")) { -// mCharmView.setVisibility(GONE); mCharmView.setSex(pitBean.getSex(), pitBean.getUser_id(), pitBean.getCharm(), false); } else { mCharmView.setVisibility(VISIBLE); @@ -727,11 +677,6 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe mIvFace.addData(new FaceBean(roomRollModel.getNumber(), 2)); } - /** - * 球球大作战开球 - * - * @param event - */ /** * 是否主持 @@ -743,30 +688,4 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe return WHEAT_HOST.equals(pitNumber); } -// @Override -// public void onRemoteSoundLevelUpdate(String userId, int volume) { -// if (userId.equals(pitBean.getUser_id())) { -// if (volume == 0) { -// mIvRipple.post(() -> { -// mIvRipple.setVisibility(GONE); -// }); -// } else { -// mIvRipple.post(() -> { -// if (!mIvRipple.isAnimating()) { -// mIvRipple.startAnimation(); -// } -// mIvRipple.setVisibility(VISIBLE); -// }); -// } -// if (pitBean.getUser_id().equals(SpUtil.getUserId()) && closePhone) { -// mIvRipple.post(() -> { -// mIvRipple.setVisibility(GONE); -// }); -// } -// } else if (userId.equals("0")) { -// mIvRipple.post(() -> { -// mIvRipple.setVisibility(GONE); -// }); -// } -// } } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/RoomSingSongWheatView.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/RoomSingSongWheatView.java index 74882384..9bb25efa 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/RoomSingSongWheatView.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/RoomSingSongWheatView.java @@ -23,7 +23,6 @@ public class RoomSingSongWheatView extends BaseWheatView { public ImageView mIvTagBoss; public TextView mTvTime; public TextView tv_time_pk; - public boolean isClickListenerSet = false; private boolean showBoss;//显示老板标识 public RoomSingSongWheatView(Context context) { @@ -65,7 +64,6 @@ public class RoomSingSongWheatView extends BaseWheatView { sex = bean.getSex(); pitBean = bean; // 统一使用参数 bean - stopAndClearAnimation(); // 清理之前的动画资源 if (isOn()) { handleOnState(bean); } else { @@ -73,13 +71,11 @@ public class RoomSingSongWheatView extends BaseWheatView { } updateSexIcon(); -// updateCharmViewVisibility(bean); updatePkState(bean); iv_on_line.setVisibility(GONE); } private void handleOnState(RoomPitBean bean) { - mIvRipple.setVisibility(VISIBLE); mTvName.setText(bean.getNickname()); ImageUtils.loadHeadCC(bean.getAvatar(), mRiv); @@ -121,7 +117,7 @@ public class RoomSingSongWheatView extends BaseWheatView { if ("-1".equals(pitNumber)) return ""; if ("9".equals(pitNumber)) return "主持位"; if ("10".equals(pitNumber)) return "嘉宾位"; - return pitNumber + "号麦位"; + return pitNumber + "号位"; } private void updateSexIcon() { @@ -149,7 +145,7 @@ public class RoomSingSongWheatView extends BaseWheatView { tv_time_pk.setVisibility(GONE); if (isOn()) { mCharmView.setVisibility(VISIBLE); - }else { + } else { mCharmView.setVisibility(GONE); } } @@ -176,18 +172,6 @@ public class RoomSingSongWheatView extends BaseWheatView { private boolean showSexIcon = false; private String sex; - public boolean isMale() { - return "1".equals(sex); - } - - public boolean isFemale() { - return "2".equals(sex); - } - - public void setShowSexIcon(boolean show) { - showSexIcon = show; - } - public void checkSex() { if (isOn()) { mIvSex.setVisibility(VISIBLE); @@ -229,14 +213,9 @@ public class RoomSingSongWheatView extends BaseWheatView { } } - public void hideMaoziIcon() { - View maozi = findViewById(R.id.iv_maozi); - if (maozi != null) maozi.setVisibility(GONE); - } // 添加内存释放方法 public void releaseResources() { - stopAndClearAnimation(); // 清理头像加载 if (mRiv != null) { @@ -263,63 +242,36 @@ public class RoomSingSongWheatView extends BaseWheatView { } } - // 停止并清理动画资源 - private void stopAndClearAnimation() { - if (mIvRipple != null) { -// mIvRipple.stopAnimation(); - mIvRipple.stopAnimation(true); - // 清理SVGA资源,避免内存泄漏 -// mIvRipple.clear(); - } - } @Override protected void onDetachedFromWindow() { - // 视图从窗口分离时释放资源 - releaseResources(); super.onDetachedFromWindow(); - } - @Override - public void onRemoteSoundLevelUpdate(String userId, int soundLevel) { - // 暂无实现 - } - @Override - public void onLocalSoundLevelUpdate(int volume) { - if (mIvRipple == null) { - return; - } - if (volume == 0) { - mIvRipple.setVisibility(GONE); - mIvRipple.stopAnimation(true); - } else { - // 增加空指针检查 - if (pitBean != null && pitBean.getUser_id() != null && - pitBean.getUser_id().equals(SpUtil.getUserId()) && closePhone) { - mIvRipple.stopAnimation(true); - } else { - mIvRipple.post(() -> { - mIvRipple.setVisibility(VISIBLE); - mIvRipple.startAnimation(); - - }); - } - } - } - - @Override - public void userJoined(int userId, int elapsd) { - // 暂无实现 - } - - @Override - public void userOffline(int userId, int reason) { - // 暂无实现 } @Override public void unRegister(Object obj) { } + + @Override + public void onRemoteSoundLevelUpdate(String userId, int soundLevel) { + + } + + @Override + public void onLocalSoundLevelUpdate(int volume) { + + } + + @Override + public void userJoined(int userId, int elapsd) { + + } + + @Override + public void userOffline(int userId, int reason) { + + } } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java index 64bd69d0..c08f23a8 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java @@ -1,6 +1,5 @@ package com.xscm.moduleutil.widget; -import android.app.Activity; import android.content.Context; import android.util.DisplayMetrics; import android.view.View; @@ -9,17 +8,15 @@ import android.widget.LinearLayout; import androidx.annotation.Nullable; +import com.google.android.material.snackbar.Snackbar; import com.hjq.toast.ToastUtils; import com.xscm.moduleutil.R; import com.xscm.moduleutil.bean.RoomMessageEvent; import com.xscm.moduleutil.bean.UserOnlineStatusBean; import com.xscm.moduleutil.bean.room.RoomPitBean; -import com.xscm.moduleutil.utils.SpUtil; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; /** * @Author lxj$ @@ -466,40 +463,6 @@ public class WheatLayoutSingManager { } return null; } - - /** - * 批量刷新多个麦位状态 - */ - public void refreshWheatData(List newPitList, List changedPits) { - // 检查容器状态 - if (container == null || !isContainerValid()) { - return; - } - - this.pitList = newPitList; - // 注意:原代码中此方法体为空,如果需要实现请取消注释下面的代码 - // for (int pitNumber : changedPits) { - // updateSingleWheat(pitNumber); - // } - } - - public void updateSingleOnlineWheat(UserOnlineStatusBean bean) { - // 检查容器状态 - if (container == null || !isContainerValid()) { - return; - } - - if (pitList == null || pitList.isEmpty()) return; - - for (RoomPitBean pitBean : pitList) { - int pitNumber = Integer.parseInt(pitBean.getPit_number()); - RoomSingSongWheatView wheatView = findWheatViewByPitNumber(pitNumber); - if (wheatView != null) { - wheatView.setOnlineStatus(); // 刷新数据 - } - } - } - // 添加容器状态检查方法 private boolean isContainerValid() { try { @@ -513,30 +476,13 @@ public class WheatLayoutSingManager { // 添加资源清理方法 public void release() { try { - if (multiWheatViews!=null){ for (RoomSingSongWheatView wheatView : multiWheatViews) { wheatView.releaseResources(); } } - if (container != null) { - // 清理所有子视图的资源 -// for (int i = 0; i < container.getChildCount(); i++) { -// View child = container.getChildAt(i); -// if (child instanceof LinearLayout) { -// LinearLayout linearLayout = (LinearLayout) child; -// for (int j = 0; j < linearLayout.getChildCount(); j++) { -// View view = linearLayout.getChildAt(j); -// if (view instanceof RoomSingSongWheatView) { -// ((RoomSingSongWheatView) view).releaseResources(); -// } -// } -// } else if (child instanceof RoomSingSongWheatView) { -// ((RoomSingSongWheatView) child).releaseResources(); -// } -// } container.removeAllViews(); } } catch (Exception e) { diff --git a/moduleUtil/src/main/res/layout/room_view_sing_wheat.xml b/moduleUtil/src/main/res/layout/room_view_sing_wheat.xml index 824fd810..9000851e 100644 --- a/moduleUtil/src/main/res/layout/room_view_sing_wheat.xml +++ b/moduleUtil/src/main/res/layout/room_view_sing_wheat.xml @@ -57,8 +57,7 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - app:loopCount="0" - app:source="ripple3695.svga" /> + app:loopCount="0" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/modulemain/src/main/java/com/xscm/modulemain/Application.kt b/modulemain/src/main/java/com/xscm/modulemain/Application.kt new file mode 100644 index 00000000..7a1aa3d4 --- /dev/null +++ b/modulemain/src/main/java/com/xscm/modulemain/Application.kt @@ -0,0 +1,19 @@ +package com.xscm.modulemain + +import com.opensource.svgaplayer.utils.log.SVGALogger +import com.xscm.modulemain.widget.WheatLayoutSingManager +import com.xscm.moduleutil.base.CommonAppContext + +open class Application : CommonAppContext() { + + override fun onCreate() { + super.onCreate() + // 初始化并预绘制视图 二卡八列 + WheatLayoutSingManager.init(this) + WheatLayoutSingManager.getInstance().setWheatData( null) + + // 默认情况下,SVGA 内部不会输出任何 log,所以需要手动设置为 true + SVGALogger.setLogEnabled(true) + } + +} \ No newline at end of file diff --git a/modulemain/src/main/java/com/xscm/modulemain/activity/room/activity/RoomActivity.kt b/modulemain/src/main/java/com/xscm/modulemain/activity/room/activity/RoomActivity.kt index 879b758c..bf813adc 100644 --- a/modulemain/src/main/java/com/xscm/modulemain/activity/room/activity/RoomActivity.kt +++ b/modulemain/src/main/java/com/xscm/modulemain/activity/room/activity/RoomActivity.kt @@ -246,6 +246,13 @@ class RoomActivity : BaseMvpActivity(), tasksManager.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_NO_USER_ACTION) } } + isOnline = intent.getBooleanExtra("isOnline", false) + password = intent.getStringExtra("password") + roomId = intent.getStringExtra("roomId") + mRoomInfoResp = intent.getSerializableExtra("roomInfo") as RoomInfoResp? + LogUtils.dTag("RoomActivit", "doDone" + mRoomInfoResp.toString()) + taskId = intent.getStringExtra("taskId") + LogUtils.e("RoomActivity", "onNewIntent") } @@ -318,7 +325,6 @@ class RoomActivity : BaseMvpActivity(), private var bgEffectView: View? = null private fun setupEffectView() { - bgEffectView = null if (bgEffectView == null) { // 获取单例管理器 val manager = QXGiftPlayerManager.getInstance(applicationContext) @@ -379,7 +385,6 @@ class RoomActivity : BaseMvpActivity(), chatEffectView.layoutParams = chatParams } - // 从SharedPreferences获取是否关闭特效的设置 val isClose = SpUtil.getOpenEffect() != 1 QXGiftPlayerManager.getInstance(applicationContext).openOrCloseEffectViewWith(!isClose) } @@ -412,7 +417,6 @@ class RoomActivity : BaseMvpActivity(), // 只有在用户主动离开应用时才执行最小化操作 if (!userLeaving) { // 保持Activity alive,不调用finish() - minimizeToBackground() userLeaving = false // 重置标记 @@ -449,11 +453,13 @@ class RoomActivity : BaseMvpActivity(), "您确定要结束本次拍卖吗?", "确认", "取消", - { v: View? -> + { // 点击“确认”按钮时执行删除操作 MvpPre!!.auctionEnd(SpUtil.getauctionId(), roomId) }, - { v: View? -> }, false, 0 + { + // 点击“取消”按钮时取消操作 + }, false, 0 ).show() } @@ -488,17 +494,12 @@ class RoomActivity : BaseMvpActivity(), // 调用退出房间方法 MessageListenerSingleton.quitGroup(roomId); quit(); - if (mRoomInfoResp?.getRoom_info() - ?.getLabel_id() != null && mRoomInfoResp?.getRoom_info() - ?.getLabel_id() - .equals("5") - ) { - jiaR(); - return; + if (mRoomInfoResp?.room_info?.label_id != null && mRoomInfoResp?.room_info?.label_id.equals("5")) { + jiaR() + return } else { performExitRoom(1); } -// performExitRoom(1) } override fun onCancel() { @@ -664,7 +665,6 @@ class RoomActivity : BaseMvpActivity(), ) mBinding!!.roomTop.btnFollow.setTextColor(ColorManager.getInstance().buttonColorInt) mBinding!!.roomTop.btnFollow.text = "收藏" - // mBinding.roomTop.btnFollow.setBackground(getResources().getDrawable(com.xscm.moduleutil.R.mipmap.collect)); } if ((roomBean.type_id == "3" || roomBean.type_id == "1" || roomBean.type_id == "4") && roomBean.label_id == "2") { AgoraManager.getInstance(this).isBjMusic = false @@ -747,6 +747,7 @@ class RoomActivity : BaseMvpActivity(), var redListDialog: RedListDialog? = null var redPacketInfo: RedPacketInfo? = null + @SuppressLint("ClickableViewAccessibility") override fun initView() { super.initView() floatingMagnetView = findViewById(R.id.flaoat) @@ -810,12 +811,9 @@ class RoomActivity : BaseMvpActivity(), mBinding!!.drvRed.visibility = View.GONE mBinding!!.redBj.setOnClickListener { - if (qxRedPacketManager!!.getAllRedPackets().size == 1) { - redPacketInfo = qxRedPacketManager!!.getAllRedPackets().get(0) - if (qxRedPacketManager!!.getAllRedPackets() - .get(0) != null && qxRedPacketManager!!.getAllRedPackets() - .get(0).is_qiang == 1 - ) { + if (qxRedPacketManager!!.allRedPackets.size == 1) { + redPacketInfo = qxRedPacketManager!!.allRedPackets[0] + if (qxRedPacketManager!!.allRedPackets[0] != null && qxRedPacketManager!!.allRedPackets[0].is_qiang == 1) { ARouter.getInstance().build(ARouteConstants.ROOM_RED_RESULT) .withString( "redpacketId", @@ -827,7 +825,7 @@ class RoomActivity : BaseMvpActivity(), redEnvelopesFragment!!.setIsCollectedRoom(mRoomUserBean!!.is_collect == 1) redEnvelopesFragment!!.setFromToComment(false) redEnvelopesFragment!!.setRedPacket( - qxRedPacketManager!!.getAllRedPackets().get(0) + qxRedPacketManager!!.allRedPackets[0] ) redEnvelopesFragment!!.show() } @@ -835,25 +833,21 @@ class RoomActivity : BaseMvpActivity(), } redListDialog = RedListDialog(this) - redListDialog!!.setOnRedPacketClickListener(object : - RedListDialog.OnRedPacketClickListener { - - override fun onRedPacketClick(redPacketInfos: RedPacketInfo?, position: Int) { - redPacketInfo = redPacketInfos - if (redPacketInfos != null && redPacketInfos.is_qiang == 1) { - ARouter.getInstance().build(ARouteConstants.ROOM_RED_RESULT) - .withString("redpacketId", redPacketInfos.getRedpacket_id()) - .navigation(); - } else { - redEnvelopesFragment = RedEnvelopesFragment(this@RoomActivity) - redEnvelopesFragment!!.setIsCollectedRoom(mRoomUserBean!!.is_collect == 1) - redEnvelopesFragment!!.setFromToComment(false) - redEnvelopesFragment!!.setRedPacket(redPacketInfos) - redEnvelopesFragment!!.show() - redListDialog!!.dismiss() - } + redListDialog!!.setOnRedPacketClickListener { redPacketInfos, position -> + redPacketInfo = redPacketInfos + if (redPacketInfos != null && redPacketInfos.is_qiang == 1) { + ARouter.getInstance().build(ARouteConstants.ROOM_RED_RESULT) + .withString("redpacketId", redPacketInfos.getRedpacket_id()) + .navigation(); + } else { + redEnvelopesFragment = RedEnvelopesFragment(this@RoomActivity) + redEnvelopesFragment!!.setIsCollectedRoom(mRoomUserBean!!.is_collect == 1) + redEnvelopesFragment!!.setFromToComment(false) + redEnvelopesFragment!!.setRedPacket(redPacketInfos) + redEnvelopesFragment!!.show() + redListDialog!!.dismiss() } - }) + } redListDialog!!.show(); } } @@ -914,8 +908,6 @@ class RoomActivity : BaseMvpActivity(), giftGiveEvent!!.heart_id, object : BaseObserver() { override fun onSubscribe(d: Disposable) { -// showGiftGiveProgress(); -// LogUtils.e("xj", "onSubscribe"); } override fun onNext(s: String) { @@ -1243,6 +1235,7 @@ class RoomActivity : BaseMvpActivity(), private var pendingRoomId: String? = null private var lastSwitchedRoomId = "" + @SuppressLint("CommitTransaction") fun roomInfoEvent(messageEvent: RoomMessageEvent?) { if (messageEvent == null) return if (roomFragment == null) { @@ -1274,7 +1267,6 @@ class RoomActivity : BaseMvpActivity(), giftBean.number = messageEvent.text.gift_num.toInt() GiftDisplayManager.getInstance().receiveGift(giftBean) } -// } hand1005(messageEvent, text) } else if (msgType == 123) { EventBus.getDefault().post(RoomSettingEvent()) @@ -1297,11 +1289,11 @@ class RoomActivity : BaseMvpActivity(), } else if (msgType == 1024) { handleMsgType1024(messageEvent, text) } else if (msgType == 1025) { - roomFragment!!.handleAuctionMessageEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else if (msgType == 1026) { - roomFragment!!.handleAuctionMessageEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else if (msgType == 1027) { - roomFragment!!.handleAuctionMessageEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else if (msgType == 1020) { handleMsgType1020(messageEvent, text) } else if (msgType == 1011) { @@ -1333,7 +1325,7 @@ class RoomActivity : BaseMvpActivity(), } else if (msgType == 1035) { handleMsgType1035(messageEvent, text) } else if (msgType == 1030 || msgType == 1031 || msgType == 1032 || msgType == 1033 || msgType == 1015 || msgType == 1037) { - roomFragment!!.SingSongEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) if (msgType == 1032 || msgType == 1033) { setRoleType(3, -11) } @@ -1361,7 +1353,7 @@ class RoomActivity : BaseMvpActivity(), var userId = messageEvent!!.text!!.user_id!! LogUtils.e("messageEvent!!.text.type" + messageEvent!!.text.type) CommonAppContext.getInstance().onlineMap.set( - userId?.toString() ?: "", + userId ?: "", messageEvent!!.text.type ) if (mRoomInfoResp != null && mRoomInfoResp!!.room_info != null) { @@ -1371,12 +1363,12 @@ class RoomActivity : BaseMvpActivity(), if (mRoomInfoResp!!.room_info.label_id == "1") { // roomFragment!!.SingSongEvent(messageEvent) } else { - roomFragment!!.KtvFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } } else if (mRoomInfoResp!!.room_info.type_id == "2") { - roomFragment!!.handleAuctionMessageEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else if (mRoomInfoResp!!.room_info.type_id == "7") { - roomFragment!!.friendshipRoomFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } } @@ -1387,14 +1379,14 @@ class RoomActivity : BaseMvpActivity(), mRoomInfoResp!!.room_info.type_id == "4" || mRoomInfoResp!!.room_info.type_id == "8" ) { if (mRoomInfoResp!!.room_info.label_id == "1") { - roomFragment!!.SingSongEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else { - roomFragment!!.KtvFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } } else if (mRoomInfoResp!!.room_info.type_id == "2") { - roomFragment!!.handleAuctionMessageEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else if (mRoomInfoResp!!.room_info.type_id == "7") { - roomFragment!!.friendshipRoomFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } } } else if (msgType == 1056) { // 1056 抽奖结果 @@ -1663,16 +1655,16 @@ class RoomActivity : BaseMvpActivity(), val typeId = mRoomInfoResp!!.room_info.type_id if ("2" == typeId) { - roomFragment!!.handleAuctionMessageEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else if ("3" == typeId || "4" == typeId || "1" == typeId || "8" == typeId) { val labelId = mRoomInfoResp!!.room_info.label_id if ("2" == labelId) { - roomFragment!!.KtvFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else if ("1" == labelId) { - roomFragment!!.SingSongEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } } else if ("7" == typeId) { - roomFragment!!.friendshipRoomFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } if (mRoomInfoResp!!.user_info.pit_number == 9) { mBinding!!.roomTop.rl.visibility = View.VISIBLE @@ -1692,19 +1684,19 @@ class RoomActivity : BaseMvpActivity(), // roomFragment.updateSeatViewExchangedWithPitArray(mRoomInfoResp); val typeId = mRoomInfoResp!!.room_info.type_id if ("2" == typeId) { - roomFragment!!.handleAuctionMessageEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) return } else if ("1" == typeId || "4" == typeId || "3" == typeId || "8" == typeId) { val labelId = mRoomInfoResp!!.room_info.label_id if ("2" == labelId) { - roomFragment!!.KtvFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) return } else if ("1" == labelId) { - roomFragment!!.SingSongEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) return } } else if ("7" == typeId) { //交友房 - roomFragment!!.friendshipRoomFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) return } } @@ -1735,7 +1727,7 @@ class RoomActivity : BaseMvpActivity(), } else if (text.action == 4 && text.fromUserInfo.user_id == userId2) { queren1(text.fromUserInfo.nickname) } else { - roomFragment?.KtvFragmentEvent(messageEvent) + roomFragment?.handleRoomMessage(messageEvent) } } @@ -1826,33 +1818,27 @@ class RoomActivity : BaseMvpActivity(), } } roomFragment!!.upRoomInfoData(mRoomInfoResp) - roomFragment!!.handleAuctionMessageEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else if ("3" == typeId || "4" == typeId || "1" == typeId || "8" == typeId) { val labelId = mRoomInfoResp!!.room_info.label_id if ("2" == labelId) { - roomFragment!!.KtvFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else if ("1" == labelId) { mRoomInfoResp!!.room_info.pit_list.set( pitNumber.toInt() - 1, getPitBean(messageEvent) ) roomFragment!!.upRoomInfoData(mRoomInfoResp) - roomFragment!!.SingSongEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } } else if ("7" == typeId) { mBinding!!.rlMore.visibility = View.GONE mBinding!!.rlMisc.visibility = View.GONE - roomFragment!!.friendshipRoomFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else { roomFragment!!.updateSeatViewExchangedWithPitArray(mRoomInfoResp) } - - // if (pitNumber.equals("9") && mRoomInfoResp.getUser_info().getUser_id().equals(SpUtil.getUserId()+"")) { -// ivSoundEffects(true); -// } else { -// ivSoundEffects(false); -// } } private fun handleMsgType1004(messageEvent: RoomMessageEvent, text: T?) { @@ -1906,24 +1892,24 @@ class RoomActivity : BaseMvpActivity(), } } roomFragment!!.upRoomInfoData(mRoomInfoResp) - roomFragment!!.handleAuctionMessageEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else if ("3" == typeId || "4" == typeId || "1" == typeId || "8" == typeId) { val labelId = mRoomInfoResp!!.room_info.label_id if ("2" == labelId) { - roomFragment!!.KtvFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else if ("1" == labelId) { mRoomInfoResp!!.room_info.pit_list.set( pitNumber.toInt() - 1, getPitBean2(messageEvent, pitNumber) ) roomFragment!!.upRoomInfoData(mRoomInfoResp) - roomFragment!!.SingSongEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) if (mRoomInfoResp!!.user_info.user_id == SpUtil.getUserId().toString() + "") { ivSoundEffects(false) } } } else { - roomFragment!!.friendshipRoomFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } } @@ -1959,7 +1945,7 @@ class RoomActivity : BaseMvpActivity(), } roomFragment!!.upRoomInfoData(mRoomInfoResp) - roomFragment!!.handleAuctionMessageEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } private fun handleMsgType1023(messageEvent: RoomMessageEvent, text: T?) { @@ -1968,8 +1954,7 @@ class RoomActivity : BaseMvpActivity(), mRoomInfoResp!!.room_auction.auction_user = text.auction_user SpUtil.setAuctionId(text.auction_user.auction_id) roomFragment!!.upRoomInfoData(mRoomInfoResp) - roomFragment!!.handleAuctionMessageEvent(messageEvent) - // roomFragment.updateSeatViewExchangedWithPitArray(mRoomInfoResp); + roomFragment!!.handleRoomMessage(messageEvent) } private fun handleMsgType1024(messageEvent: RoomMessageEvent, text: T?) { @@ -1981,11 +1966,9 @@ class RoomActivity : BaseMvpActivity(), mRoomInfoResp!!.room_auction.auction_list.addAll(text.auction_list) } else { mRoomInfoResp!!.room_auction.auction_list = ArrayList() - // mRoomInfoResp.getRoom_auction().getAuction_list().addAll(text.getAuction_list()); } roomFragment!!.upRoomInfoData(mRoomInfoResp) - roomFragment!!.handleAuctionMessageEvent(messageEvent) - // roomFragment.updateSeatViewExchangedWithPitArray(mRoomInfoResp); + roomFragment!!.handleRoomMessage(messageEvent) } private fun handleMsgType1020(messageEvent: RoomMessageEvent, text: T?) { @@ -2042,15 +2025,15 @@ class RoomActivity : BaseMvpActivity(), val typeId = mRoomInfoResp!!.room_info.type_id if ("2" == typeId) { - roomFragment!!.handleAuctionMessageEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else if ("1" == typeId || "4" == typeId || "3" == typeId || "8" == typeId) { val labelId = mRoomInfoResp!!.room_info.label_id if ("2" == labelId) { - roomFragment!!.KtvFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else { updateCharmForAllPitBeans("") roomFragment!!.upRoomInfoData(mRoomInfoResp) - roomFragment!!.SingSongEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } } else { updateCharmForAllPitBeans("") @@ -2189,19 +2172,18 @@ class RoomActivity : BaseMvpActivity(), val typeId = mRoomInfoResp!!.room_info.type_id if ("2" == typeId) { - roomFragment!!.handleAuctionMessageEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else if ("1" == typeId || "3" == typeId || "4" == typeId || "8" == typeId) { val labelId = mRoomInfoResp!!.room_info.label_id if ("2" == labelId) { - roomFragment!!.KtvFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } else { -// updatePitBeanForUser(fromUserInfo); roomFragment!!.upRoomInfoData(updatePitBeanForUser(fromUserInfo)) - roomFragment!!.SingSongEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } } else { roomFragment!!.upRoomInfoData(updatePitBeanForUser(fromUserInfo)) - roomFragment!!.friendshipRoomFragmentEvent(messageEvent) + roomFragment!!.handleRoomMessage(messageEvent) } } @@ -3955,7 +3937,6 @@ class RoomActivity : BaseMvpActivity(), } else if ("1" == labelId) { changeBackgroundColor(mRoomInfoResp!!.room_info.room_background) setvisibTop(true) - // sharedViewModel.setSeatViewType(QXRoomSeatViewType.NORMAL); roomFragment!!.refreshData(mRoomInfoResp, QXRoomSeatViewType.NORMAL) } } else if ("6" == typeId) { diff --git a/modulemain/src/main/java/com/xscm/modulemain/activity/room/fragment/RoomFragment.java b/modulemain/src/main/java/com/xscm/modulemain/activity/room/fragment/RoomFragment.java index ae980dda..5082cc42 100644 --- a/modulemain/src/main/java/com/xscm/modulemain/activity/room/fragment/RoomFragment.java +++ b/modulemain/src/main/java/com/xscm/modulemain/activity/room/fragment/RoomFragment.java @@ -6,6 +6,7 @@ import android.os.CountDownTimer; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -14,6 +15,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; import com.blankj.utilcode.util.LogUtils; @@ -52,6 +54,7 @@ import org.greenrobot.eventbus.ThreadMode; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.List; +import java.util.Objects; /** * @author qx @@ -66,10 +69,11 @@ public class RoomFragment extends BaseMvpFragment { - if (isAdded() && getActivity() != null) { - getChildFragmentManager() - .beginTransaction() - .replace(R.id.container, singSongFragment) - .commitAllowingStateLoss(); - } - }); - } - } - } - - private void releaseKtvFragment() { - if (ktvFragment != null) { - ktvFragment.releaseResources(); - ktvFragment = null; - } - } - - private void createKtvFragment() { - if (ktvFragment == null) { - ktvFragment = RoomKtvFragment.newInstance(mRoomInfoResp); - // 确保 Fragment 已添加且处于活跃状态再进行操作 - if (isAdded() && getActivity() != null) { - getChildFragmentManager() - .beginTransaction() - .replace(R.id.container, ktvFragment) - .commitAllowingStateLoss(); - } else if (getView() != null) { - // 延迟执行直到 Fragment 处于合适状态 - getView().post(() -> { - if (isAdded() && getActivity() != null) { - getChildFragmentManager() - .beginTransaction() - .replace(R.id.container, ktvFragment) - .commitAllowingStateLoss(); - } - }); - } - } - } - - private void releaseRoomAuctionFragment() { - if (roomAuctionFragment != null) { - roomAuctionFragment.releaseResources(); - roomAuctionFragment = null; - } - } - - private void createRoomAuctionFragment() { - if (roomAuctionFragment == null) { - roomAuctionFragment = RoomAuctionFragment.newInstance(mRoomInfoResp); - // 确保 Fragment 已添加且处于活跃状态再进行操作 - if (isAdded() && getActivity() != null) { - getChildFragmentManager() - .beginTransaction() - .replace(R.id.container, roomAuctionFragment) - .commitAllowingStateLoss(); - } else if (getView() != null) { - // 延迟执行直到 Fragment 处于合适状态 - getView().post(() -> { - if (isAdded() && getActivity() != null) { - getChildFragmentManager() - .beginTransaction() - .replace(R.id.container, roomAuctionFragment) - .commitAllowingStateLoss(); - } - }); - } - } - } - - private void releaseFriendshipRoomFragment() { - if (friendshipRoomFragment != null) { - friendshipRoomFragment.releaseResources(); - friendshipRoomFragment = null; - } - } - - private void createFriendshipRoomFragment() { - if (friendshipRoomFragment == null) { - friendshipRoomFragment = FriendshipRoomFragment.newInstance(mRoomInfoResp); - // 确保 Fragment 已添加且处于活跃状态再进行操作 - if (isAdded() && getActivity() != null) { - getChildFragmentManager() - .beginTransaction() - .replace(R.id.container, friendshipRoomFragment) - .commitAllowingStateLoss(); - } else if (getView() != null) { - // 延迟执行直到 Fragment 处于合适状态 - getView().post(() -> { - if (isAdded() && getActivity() != null) { - getChildFragmentManager() - .beginTransaction() - .replace(R.id.container, friendshipRoomFragment) - .commitAllowingStateLoss(); - } - }); - } - } - } - - private void releaseRoomCabinFragment() { - if (roomCabinFragment != null) { - roomCabinFragment.releaseResources(); - roomCabinFragment = null; - } - } - - private void createRoomCabinFragment() { - if (roomCabinFragment == null) { - roomCabinFragment = RoomCabinFragment.newInstance(mRoomInfoResp); - // 确保 Fragment 已添加且处于活跃状态再进行操作 - if (isAdded() && getActivity() != null) { - getChildFragmentManager() - .beginTransaction() - .replace(R.id.container, roomCabinFragment) - .commitAllowingStateLoss(); - } else if (getView() != null) { - // 延迟执行直到 Fragment 处于合适状态 - getView().post(() -> { - if (isAdded() && getActivity() != null) { - getChildFragmentManager() - .beginTransaction() - .replace(R.id.container, roomCabinFragment) - .commitAllowingStateLoss(); - } - }); - } - } - } public void onFragmentShowDestroy() { if (EventBus.getDefault().isRegistered(this)) { @@ -448,16 +234,16 @@ public class RoomFragment extends BaseMvpFragment T findFragmentByTag(Class fragmentClass) { return (T) getChildFragmentManager().findFragmentByTag(fragmentClass.getSimpleName()); } - private void upView(QXRoomSeatViewType qxRoomSeatViewType) { - this.qxRoomSeatViewType = qxRoomSeatViewType; - switch (qxRoomSeatViewType) { - case KTV: - if (ktvFragment != null && ktvFragment.isAdded()) { - ktvFragment.roomInfoUpdate(mRoomInfoResp); - } else { - setqxRoomSeatViewType(qxRoomSeatViewType); - } - break; - case AUCTION: - if (roomAuctionFragment != null && roomAuctionFragment.isAdded()) { -// roomAuctionFragment.roomInfoUpdate(mRoomInfoResp); - } else { - setqxRoomSeatViewType(qxRoomSeatViewType); - } - break; - case CABIN: - if (roomCabinFragment != null && roomCabinFragment.isAdded()) { - roomCabinFragment.roomInfoUpdate(mRoomInfoResp); - } else { - setqxRoomSeatViewType(qxRoomSeatViewType); - } - break; - case FRIEND: - if (friendshipRoomFragment != null) { - friendshipRoomFragment.roomInfoUpdate(mRoomInfoResp); - } else { - setqxRoomSeatViewType(qxRoomSeatViewType); - } - break; - case NORMAL: - if (singSongFragment != null && singSongFragment.isAdded()) { - singSongFragment.roomInfoUpdate(mRoomInfoResp); - } else { - setqxRoomSeatViewType(qxRoomSeatViewType); - } - break; - default: - break; - } - } public void updateChildFragmentViews() { @@ -523,8 +264,6 @@ public class RoomFragment extends BaseMvpFragment { if (mRoomInfoResp != null && mRoomInfoResp.getRoom_info() != null) { String typeId = mRoomInfoResp.getRoom_info().getType_id(); String labelId = mRoomInfoResp.getRoom_info().getLabel_id(); @@ -532,45 +271,34 @@ public class RoomFragment extends BaseMvpFragment { - if (isAdded() && getActivity() != null) { - performLoadSubFragment(qxRoomSeatViewType); - }else { -// loadSubFragment(qxRoomSeatViewType); - } - }); - } - return; - } - performLoadSubFragment(qxRoomSeatViewType); - } + private void performLoadSubFragment(QXRoomSeatViewType qxRoomSeatViewType) { this.qxRoomSeatViewType = qxRoomSeatViewType; if (mRoomInfoResp == null || mRoomInfoResp.getRoom_info() == null) return; @@ -656,49 +368,57 @@ public class RoomFragment extends BaseMvpFragment pitList; - private SharedViewModel sharedViewModel; + // 添加防重复点击的时间戳 + private static final long CLICK_INTERVAL = 500; // 500ms内不允许重复点击 + private long lastClickTime = 0; + private String lastClickedUserId = ""; // 记录上次点击的用户ID + private String lastClickedPitNumber = ""; // 记录上次点击的麦位号 + private FlexboxLayout flexboxLayout; public static SingSongFragment newInstance(RoomInfoResp roomInfoResp) { Bundle args = new Bundle(); @@ -132,11 +129,66 @@ public class SingSongFragment extends BaseRoomFragment { -// upDtaView(true); -// }); - Observable.timer(10, TimeUnit.MILLISECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(aLong -> { - upDtaView(false); - }); - - } - public void upRoomInfo(RoomInfoResp roomInfoResp) { - this.roomInfoResp = roomInfoResp; - } - - private void upDtaView(boolean isFirst) { + private void upDtaView() { pitList = new ArrayList<>(); if (getActivity() instanceof RoomActivity) { ((RoomActivity) getActivity()).setvisibTop(true); @@ -181,11 +216,10 @@ public class SingSongFragment extends BaseRoomFragment { -// if (data != null) { -// // 处理数据 -// roomInfoUpdate(data); -// } -// }); - roomId = roomInfoResp.getRoom_info().getRoom_id(); - initPopupWindow(); - - return super.onCreateView(inflater, container, savedInstanceState); - } /** * 这是判断当前用户是否是麦上房主、管理员、主持,不在主持麦的都是不同用户 @@ -265,13 +282,6 @@ public class SingSongFragment extends BaseRoomFragment 8) { -// if (roomInfoResp.getRoom_info().getPit_list().get(8).getUser_id().equals(SpUtil.getUserId() + "") && !pitNumber.equals("10")) { if (roomInfoResp.getUser_info().getPit_number() == 9 && !pitNumber.equals("10")) { return true; } @@ -371,8 +376,6 @@ public class SingSongFragment extends BaseRoomFragment pitList = new ArrayList<>(); - for (int i = 1; i <= 10; i++) { - RoomPitBean pitBean = new RoomPitBean(); - pitBean.setPit_number("" + i); - pitBean.setUser_id("0"); - pitBean.setCharm(""); - pitList.add(pitBean); - } - wheatLayoutSingManager.setWheatData(pitList, false); - } else { -// if (roomInfoResp.getPk_info() == null) { -// -// -// if (!ObjectUtils.isEmpty(roomInfoResp.getRoom_info().getPit_list()) && roomInfoResp.getRoom_info().getPit_list().size() == 10) { -// wheatLayoutSingManager.setWheatData(roomInfoResp.getRoom_info().getPit_list()); -// } -//// initWheatLayout(); -// } else { -// mBinding.flexboxLayout.setVisibility(View.GONE); -// mBinding.cl.setVisibility(View.VISIBLE); -// MvpPre.postRoomInfo(roomInfoResp.getPk_info().getPk_room_id(), roomInfoResp.getUser_info().getPit_number() + "", 1); -// -// } -// -// if (roomInfoResp.getUser_info().getPit_number() != 9) { -// mBinding.imMkf.setVisibility(GONE); -// } else { -// mBinding.imMkf.setVisibility(VISIBLE); -// } -// -// tzblChanged(); - } - - mBinding.btSta.setOnClickListener(this::onClick); - mBinding.btStop.setOnClickListener(this::onClick); - mBinding.imMkf.setOnClickListener(this::onClick); - - } - - /** - * 检查当前用户是否是房间的主持人 - * - * @return true表示是主持人,false表示不是主持人或数据不完整 - */ - private boolean isUserHostOfRoom() { - // 先检查列表是否为空或大小不足 - if (ObjectUtils.isEmpty(roomInfoResp.getRoom_info().getPit_list()) || - roomInfoResp.getRoom_info().getPit_list().size() < 10) { - return false; - } - - // 检查第9个麦位(索引为8)的用户ID是否存在且与当前用户ID匹配 - RoomPitBean hostPitBean = roomInfoResp.getRoom_info().getPit_list().get(8); - if (hostPitBean == null) { - return false; - } - - String hostUserId = hostPitBean.getUser_id(); - return hostUserId != null && - !hostUserId.isEmpty() && - hostUserId.equals(SpUtil.getUserId() + ""); - } - - public void onWheatClicked(View ii) { - RoomDefaultWheatView view = (RoomDefaultWheatView) ii; - if (view.isOn()) { - EventBus.getDefault().post(new UserInfoShowEvent(roomId, view.pitBean.getUser_id())); - } else { - if (roomInfoResp.getRoom_info().getPit_list().get(8).getUser_id().equals(SpUtil.getUserId())) { - if (!DoubleUtils.isFastDoubleClick()) { - //弹出空麦位弹窗 -// RoomWheatManageDialogFragment roomWheatManageDialogFragment = RoomWheatManageDialogFragment.newInstance(roomId, view.pitNumber, view.pitBean.getShutup(), false, true); -// roomWheatManageDialogFragment.show(getChildFragmentManager()); - } - return; - } else if (roomInfoResp.isWheatManager() || (roomInfoResp.isManager() && view.isLocked())) { - if (!DoubleUtils.isFastDoubleClick()) { - //弹出空麦位弹窗 -// RoomWheatManageDialogFragment roomWheatManageDialogFragment = RoomWheatManageDialogFragment.newInstance(roomId, view.pitNumber, view.pitBean.getShutup(), false, true); -// roomWheatManageDialogFragment.show(getChildFragmentManager()); - } - return; - } - if (roomInfoResp.isFreedomMode()) {//自由模式 - MvpPre.applyWheat(roomId, view.pitNumber); - } else {//排麦模式 - //普通用户排麦模式弹出提示框 - if (!roomInfoResp.isManager()) { - showConfirmApplyWait(); - } else { - MvpPre.applyWheatWait(roomId, view.pitNumber); - } - } - } - pitNumber = view.pitNumber; - } - - protected void showConfirmApplyWait() { - if (commonDialog == null) { - commonDialog = new CommonDialog(requireContext()); - commonDialog.setContent("是否加入当前麦序队列"); - commonDialog.setmOnClickListener(new CommonDialog.OnClickListener() { - @Override - public void onLeftClick() { - - } - - @Override - public void onRightClick() { - MvpPre.applyWheatWait(roomId, pitNumber); - } - }); - } - if (!commonDialog.isShowing()) { - commonDialog.show(); - } - } // TODO: 2025/3/26 进入房间 @Subscribe(threadMode = ThreadMode.MAIN) @@ -768,7 +545,7 @@ public class SingSongFragment extends BaseRoomFragment list) { -// if (list != null) { -// for (int i = 0; i < list.size(); i++) { -// if (roomInfoRespPk == null || roomInfoRespPk.getPk_info() == null) { -// wheatLayoutSingManager.updateSingleOnlineWheat(list.get(i)); -// } else { -// wheatLayoutManager1.updateSingleOnlineWheat(list.get(i)); -// } -//// EventBus.getDefault().post(list.get(i)); -// } -// } - if (list != null) { for (int i = 0; i < list.size(); i++) { String userOnlineStatusBean = list.get(i).getUser_id(); @@ -895,22 +651,21 @@ public class SingSongFragment extends BaseRoomFragment { -// countDownTimer.cancel(); // 取消倒计时 -// dialog.dismiss(); // 手动关闭对话框 -// }); - Window window = dialog.getWindow(); if (window != null) { window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); @@ -1699,13 +1406,6 @@ public class SingSongFragment extends BaseRoomFragment? = null + + // 单麦模式标记 + private var isSingleMode = false + private var currentSinglePit = -1 + private var singleWheatView: RoomSingSongWheatView? = null + private val multiWheatViews = mutableListOf() + + // 麦位索引映射 + private val pitIndexMap = intArrayOf(9, 10, 1, 2, 3, 4, 5, 6, 7, 8) + + // 预加载时的尺寸(基于屏幕尺寸预估) + private val preloadWidth: Int by lazy { + appContext.resources.displayMetrics.widthPixels - + appContext.resources.getDimensionPixelSize(R.dimen.dp_5) * 2 + } + private val preloadHeight: Int by lazy { + appContext.resources.displayMetrics.heightPixels / 2 // 预估高度为屏幕一半 + } + + // 初始化时立即执行预绘制 + init { + preDrawContainer() + } + + /** + * 预绘制容器(核心预加载逻辑) + * 手动触发测量、布局、绘制流程,生成缓存 + */ + private fun preDrawContainer() { + // 1. 测量:使用预估尺寸,AT_MOST模式适配wrap_content + rootContainer.measure( + View.MeasureSpec.makeMeasureSpec(preloadWidth, View.MeasureSpec.AT_MOST), + View.MeasureSpec.makeMeasureSpec(preloadHeight, View.MeasureSpec.AT_MOST) + ) + + // 2. 布局:指定位置(左上角为0,0) + rootContainer.layout( + 0, + 0, + rootContainer.measuredWidth, + rootContainer.measuredHeight + ) + + // 3. 绘制:强制触发绘制,生成缓存 + rootContainer.draw(Canvas()) + } + + /** + * 获取预绘制好的根容器,供外部添加到FlexboxLayout + */ + fun getRootContainer(): LinearLayout = rootContainer + + /** + * 设置麦位数据并刷新视图 + */ + fun setWheatData(pitList: List?) { + this.pitList = pitList + restoreMultiWheat() + // 数据更新后重新预绘制,确保缓存同步 + preDrawContainer() + } + + /** + * 为麦位视图设置点击事件(确保使用最新的 wheatClickListener) + */ + private fun setupViewListeners(wheatView: RoomSingSongWheatView, pitNumber: Int) { + // 头像点击事件 + val avatarView = wheatView.mRiv as GifAvatarOvalView + avatarView.setOnClickListener { + // 直接使用当前的 wheatClickListener(可能已被外部设置) + wheatClickListener?.onWheatClick(wheatView, pitNumber) + } + + // 魅力值点击事件 + val charmView = wheatView.mCharmView + charmView.setOnClickListener { + ToastUtils.show("点击了麦位") + wheatClickListener?.onMeilingClick(wheatView, pitNumber) + } + + // 整体点击事件 + wheatView.setOnClickListener { + wheatClickListener?.onMeilingClick(wheatView, wheatView.pitNumber.toInt()) + } + } + + /** + * 设置麦位点击监听器(关键修改:设置后为已有视图重新绑定事件) + */ + fun setOnWheatClickListener(@Nullable listener: OnWheatClickListener?) { + this.wheatClickListener = listener + // 为已创建的所有麦位视图重新绑定点击事件(此时 listener 已生效) + multiWheatViews.forEach { view -> + val pitNumber = view.pitNumber.toIntOrNull() ?: return@forEach + setupViewListeners(view, pitNumber) + } + } + + /** + * 恢复多麦模式布局 + */ + private fun restoreMultiWheat() { + // 清空现有视图(保留缓存逻辑) + + val screenWidth = getScreenWidth() + val itemWidth = screenWidth / 4 + + var row = createHorizontalRow() + + if (multiWheatViews.size == 10) { + // 复用已有视图,仅更新数据 + multiWheatViews.forEachIndexed { i, view -> + if (pitList != null) { + view.setData(pitList!![pitIndexMap[i] - 1]) + } + } + } else { + // 创建新视图 + for (i in 0 until 10) { + val pitNumber = pitIndexMap[i] + + val wheatView = RoomSingSongWheatView(appContext).apply { + this.pitNumber = pitNumber.toString() + if (pitList != null) { + setData(pitList!![pitNumber - 1]) + } + } + multiWheatViews.add(wheatView) + + val params = getLayoutParams(i, itemWidth) + wheatView.layoutParams = params + + // 设置点击事件 + setupViewListeners(wheatView, pitNumber) + + row.addView(wheatView) + + // 换行逻辑 + handleRowBreak(i, row) { newRow -> row = newRow } + } + + // 添加最后一行剩余视图 + if (row.childCount > 0) { + rootContainer.addView(row) + } + + isSingleMode = false + currentSinglePit = -1 + } + } + + /** + * 恢复PK模式下的多麦布局 + */ + fun restoreMultiWheatPk(layoutType: Int) { + try { + if (layoutType == 1) { + rootContainer.removeAllViews() + } + } catch (e: Exception) { + return + } + + val pitList = this.pitList ?: return + if (pitList.size < 10) return + + val screenWidth = getScreenWidth() + val itemWidth = screenWidth / 8 + + var row = createHorizontalRow() + + // 调整前两个麦位顺序 + val (firstPit, secondPit) = when (layoutType) { + 1 -> Pair(10, 9) + 2 -> Pair(9, 10) + else -> Pair(9, 10) + } + + // 添加前两个麦位 + addWheatViewItem(row, firstPit, itemWidth * 2, layoutType) + addWheatViewItem(row, secondPit, itemWidth * 2, layoutType) + + rootContainer.addView(row) + row = createHorizontalRow() + + // 添加剩余8个麦位 + for (i in 2 until 10) { + val pitNumber = pitIndexMap[i] + addWheatViewItem(row, pitNumber, itemWidth, layoutType) + + if (i > 1 && (i - 2) % 4 == 3) { + rootContainer.addView(row) + row = createHorizontalRow() + } + } + + if (row.childCount > 0) { + rootContainer.addView(row) + } + + isSingleMode = false + currentSinglePit = -1 + // 预绘制更新 + preDrawContainer() + } + + /** + * 添加单个麦位视图到行布局 + */ + private fun addWheatViewItem( + row: LinearLayout, + pitNumber: Int, + itemWidth: Int, + layoutType: Int + ) { + val pitList = this.pitList ?: return + + val wheatView = RoomSingSongWheatView(appContext).apply { + this.pitNumber = pitNumber.toString() + setData(pitList[pitNumber - 1]) + } + + val params = when (pitNumber) { + 9, 10 -> { + val fixedHeight = appContext.resources.getDimensionPixelSize(R.dimen.dp_90) + if (pitNumber == 9) { + LinearLayout.LayoutParams(itemWidth - 40, fixedHeight).apply { + if (layoutType == 1) { + rightMargin = appContext.resources.getDimensionPixelSize(R.dimen.dp_1) + setMargins(20, -30, -20, 0) + } else { + leftMargin = appContext.resources.getDimensionPixelSize(R.dimen.dp_1) + setMargins(-30, -20, 0, 0) + } + } + } else { + LinearLayout.LayoutParams(itemWidth - 80, fixedHeight).apply { + if (layoutType == 1) { + setMargins(-30, 10, 0, 0) + } else { + setMargins(0, 10, -30, 0) + } + } + } + } + + else -> { + val fixedHeight = appContext.resources.getDimensionPixelSize(R.dimen.dp_60) + LinearLayout.LayoutParams(itemWidth + 15, fixedHeight + 20).apply { + setMargins(-20, -20, -20, 0) + } + } + } + + wheatView.layoutParams = params + wheatView.setOnClickListener { + wheatClickListener?.let { listener -> + val pitNum = wheatView.pitNumber.toInt() + if (layoutType == 1) { + listener.onWheatClick(wheatView, pitNum) + } else { + listener.onMakeWheatClick(wheatView, pitNum) + } + } + } + + row.addView(wheatView) + } + + /** + * 创建水平方向的行布局 + */ + private fun createHorizontalRow(): LinearLayout { + return LinearLayout(appContext).apply { + orientation = LinearLayout.HORIZONTAL + layoutParams = LinearLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ).apply { + // 添加行内居中 + gravity = Gravity.CENTER_HORIZONTAL + } + } + } + + /** + * 获取麦位视图的布局参数 + */ + private fun getLayoutParams(index: Int, itemWidth: Int): LinearLayout.LayoutParams { + return when (index) { + 0 -> { + LinearLayout.LayoutParams(itemWidth, dpToPx(110)).apply { + // 移除右间距,通过容器居中自动平衡 + rightMargin = (getScreenWidth() - (dpToPx(110) * 2)) / 2 + } + } + + 1 -> { + LinearLayout.LayoutParams(itemWidth, dpToPx(110)) + } + + else -> { + // 统一边距逻辑 + LinearLayout.LayoutParams(itemWidth - 30, dpToPx(90) + 30).apply { + setMargins(0, 0, 0, 0) + } + } + } + } + + /** + * 处理换行逻辑 + */ + private fun handleRowBreak( + index: Int, + currentRow: LinearLayout, + newRowCallback: (LinearLayout) -> Unit + ) { + when { + index == 1 -> { + rootContainer.addView(currentRow) + newRowCallback(createHorizontalRow()) + } + + index > 1 && (index - 2) % 4 == 3 -> { + rootContainer.addView(currentRow) + newRowCallback(createHorizontalRow()) + } + } + } + + + /** + * 创建麦位视图 + */ + private fun createWheatView(pitNumber: Int): RoomSingSongWheatView { + val pitList = this.pitList ?: throw IllegalArgumentException("pitList is null") + return RoomSingSongWheatView(appContext).apply { + this.pitNumber = pitNumber.toString() + setData(pitList[pitNumber - 1]) + } + } + + /** + * 创建申请麦位视图 + */ + private fun createRoomMakeWheatView(pitNumber: Int): RoomMakeWheatView { + val pitList = this.pitList ?: throw IllegalArgumentException("pitList is null") + return RoomMakeWheatView(appContext).apply { + this.pitNumber = pitNumber.toString() + setData(pitList[pitNumber - 1]) + } + } + + /** + * dp转px + */ + private fun dpToPx(dp: Int): Int { + return (dp * appContext.resources.displayMetrics.density).roundToInt() + } + + /** + * 获取屏幕宽度 + */ + private fun getScreenWidth(): Int { + return appContext.resources.displayMetrics.widthPixels + } + + /** + * 更新麦位交换数据 + */ + fun setUpData(event: RoomMessageEvent) { + val fromPit = event.text.from_pit_number ?: return + val toPitNumber = event.text.to_pit_number ?: return + + val fromWheatView = findWheatViewByPitNumber(fromPit.toInt()) + val toWheatView = findWheatViewByPitNumber(toPitNumber.toInt()) + if (fromWheatView == null || toWheatView == null) return + + // 交换麦位数据 + val fromPitBean = fromWheatView.pitBean + val toPitBean = toWheatView.pitBean + val tmpNumber = fromPitBean.pit_number + fromPitBean.pit_number = toPitBean.pit_number + toPitBean.pit_number = tmpNumber + toWheatView.setData(fromPitBean) + fromWheatView.setData(toPitBean) + + // 清空原麦位数据 + multiWheatViews.forEach { view -> + if (view.pitBean.user_id == event.text.fromUserInfo.user_id.toString() && + view.pitBean.pit_number != toPitNumber + ) { + view.pitBean.apply { + charm = "" + user_id = "" + dress = "" + avatar = "" + nickname = "" + sex = "" + user_code = "" + dress_picture = "" + } + view.setData(view.pitBean) + } + } + + // 预绘制更新 + preDrawContainer() + } + + /** + * 更新单个麦位信息 + */ + fun updateSingleWheat(pitBean: RoomPitBean, pitNumber: Int) { + if (pitNumber < 1 || pitNumber > 10) return + if (isSingleMode && currentSinglePit != pitNumber) return + + findWheatViewByPitNumber(pitNumber)?.setData(pitBean) + // 预绘制更新 + preDrawContainer() + } + + /** + * 更新麦位魅力值 + */ + fun upDataCharm(pitBean: RoomPitBean, pitNumber: Int) { + if (pitNumber < 1 || pitNumber > 10) return + if (isSingleMode && currentSinglePit != pitNumber) return + + findWheatViewByPitNumber(pitNumber)?.setCharm(pitBean.charm) + // 预绘制更新 + preDrawContainer() + } + + /** + * 根据麦位号查找视图 + */ + @Nullable + private fun findWheatViewByPitNumber(pitNumber: Int): RoomSingSongWheatView? { + for (i in 0 until rootContainer.childCount) { + val row = rootContainer.getChildAt(i) + when (row) { + is LinearLayout -> { + for (j in 0 until row.childCount) { + val child = row.getChildAt(j) + if (child is RoomSingSongWheatView && child.pitNumber.toInt() == pitNumber) { + return child + } + } + } + + is RoomSingSongWheatView -> { + if (row.pitNumber.toInt() == pitNumber) { + return row + } + } + } + } + return null + } + + /** + * 释放资源 + */ + fun release() { + try { + // 释放子视图资源 + multiWheatViews.forEach { it.releaseResources() } + multiWheatViews.clear() + // 清空容器 + rootContainer.removeAllViews() + // 从父布局移除自身 + (rootContainer.parent as? ViewGroup)?.removeView(rootContainer) + // 清除绘制缓存 + rootContainer.setLayerType(View.LAYER_TYPE_NONE, null) + } catch (e: Exception) { + // 忽略异常 + } + // 清空数据引用 + pitList = null + singleWheatView = null + wheatClickListener = null + } + + /** + * 麦位点击事件接口 + */ + interface OnWheatClickListener { + fun onWheatClick(view: RoomSingSongWheatView, pitNumber: Int) + fun onMakeWheatClick(view: RoomSingSongWheatView, pitNumber: Int) + fun onMeilingClick(view: RoomSingSongWheatView, pitNumber: Int) + } + + @Nullable + private var wheatClickListener: OnWheatClickListener? = null + + /** + * 单例实现 + */ + companion object { + @SuppressLint("StaticFieldLeak") + @Volatile + private var instance: WheatLayoutSingManager? = null + + /** + * 初始化单例(预加载视图) + * 建议在Application.onCreate()中调用 + */ + fun init(context: Context) { + if (instance == null) { + synchronized(WheatLayoutSingManager::class.java) { + if (instance == null) { + instance = WheatLayoutSingManager(context.applicationContext) + } + } + } + } + + /** + * 获取单例实例 + * 必须先调用init()初始化 + */ + fun getInstance(): WheatLayoutSingManager { + return instance + ?: throw IllegalStateException("请先调用init()初始化WheatLayoutSingManager") + } + + /** + * 销毁单例(退出应用时调用) + */ + fun destroyInstance() { + instance?.release() + instance = null + } + } + + private var svgaVideoItem: SVGAVideoEntity? = null + + + fun bindSvga(view: SVGAImageView, context: Context, assetName: String) { + if (svgaVideoItem == null) { + val parser = SVGAParser(context) + parser.decodeFromAssets(assetName, object : SVGAParser.ParseCompletion { + + override fun onComplete(videoItem: SVGAVideoEntity) { + // videoItem 可能为 null,按需处理 + videoItem.let { + svgaVideoItem = it + view.setVideoItem(it) + view.startAnimation() + } + } + + override fun onError() { + // 解析失败的处理 + Log.e("SVGA", "decodeFromAssets error: $assetName") + } + }) + + } else { + view.setVideoItem(svgaVideoItem) + view.startAnimation() + } + } + + fun releaseFromParent() { + rootContainer.let { container -> + (container.parent as? ViewGroup)?.removeView(container) + } + } + +} \ No newline at end of file diff --git a/modulemain/src/main/res/layout/fragment_room.xml b/modulemain/src/main/res/layout/fragment_room.xml index 4bbea827..28317dc9 100644 --- a/modulemain/src/main/res/layout/fragment_room.xml +++ b/modulemain/src/main/res/layout/fragment_room.xml @@ -12,239 +12,17 @@ android:clipChildren="false" android:clipToPadding="false"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + app:layout_constraintTop_toTopOf="parent" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modulemain/src/main/res/layout/fragment_sing_song.xml b/modulemain/src/main/res/layout/fragment_sing_song.xml index 04803fab..f3cd4757 100644 --- a/modulemain/src/main/res/layout/fragment_sing_song.xml +++ b/modulemain/src/main/res/layout/fragment_sing_song.xml @@ -16,42 +16,32 @@ - - - - - - - - + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent"/> + app:layout_constraintTop_toTopOf="parent" + tools:visibility="visible">