diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/base/CommonAppContext.java b/BaseModule/src/main/java/com/xscm/moduleutil/base/CommonAppContext.java index 170922cb..5505fc02 100644 --- a/BaseModule/src/main/java/com/xscm/moduleutil/base/CommonAppContext.java +++ b/BaseModule/src/main/java/com/xscm/moduleutil/base/CommonAppContext.java @@ -161,7 +161,7 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio //设置mqtt环境 false 测试环境 true 正式环境 // ExternalResConstants.INSTANCE.setIS_MQTT_RELEASE(false); //设置http环境 false 测试环境 true 正式环境 - ExternalResConstants.INSTANCE.setIS_HTTP_RELEASE(true); + ExternalResConstants.INSTANCE.setIS_HTTP_RELEASE(false); currentEnvironment = ExternalResConstants.INSTANCE.HTTP_PATH(); diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/bean/RoomMessageEvent.java b/BaseModule/src/main/java/com/xscm/moduleutil/bean/RoomMessageEvent.java index 2c5674d2..48433e72 100644 --- a/BaseModule/src/main/java/com/xscm/moduleutil/bean/RoomMessageEvent.java +++ b/BaseModule/src/main/java/com/xscm/moduleutil/bean/RoomMessageEvent.java @@ -97,6 +97,9 @@ public class RoomMessageEvent { private EmotionDeatils emoji; private String is_pk;//是否是pk + + private SingerInfo.SongInfo song_info; + private SingerInfo.SongInfo next_song_info; } @Data diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/bean/SingerInfo.java b/BaseModule/src/main/java/com/xscm/moduleutil/bean/SingerInfo.java new file mode 100644 index 00000000..c6b9f897 --- /dev/null +++ b/BaseModule/src/main/java/com/xscm/moduleutil/bean/SingerInfo.java @@ -0,0 +1,54 @@ +package com.xscm.moduleutil.bean; + +import java.io.Serializable; + +import lombok.Data; + +@Data +public class SingerInfo implements Serializable { + private static final long serialVersionUID = 1L; + private SongInfo song_info; + private SongInfo next_song_info; + + @Data + public static class SongInfo implements Serializable{ + private static final long serialVersionUID = 1L; + /*"id": 29, + "room_id": 6001, + "user_id": 20001, + "singer_song_id": 9, + "status": 1, + "sort": 0, + "createtime": 1763435086, + "boss_user_id": 20001, + "boss_nickname": "高兴的小海腾", + "boss_avatar": "https://yusheng-1369267578.cos.ap-guangzhou.myqcloud.com/images/ios_images/1761615690733.jpeg", + "boss_dress": "", + "boss_mic_cycle": "https://cos.xscmmidi.site/admin/ripple3695_17627709565119.svga", + "singer_user_id": 20000, + "singer_nickname": "坚定的故事", + "singer_avatar": "https://yusheng-1369267578.cos.ap-guangzhou.myqcloud.com/images/android_images/4ead5077435f1da7b8aae1a878bb5ac9.jpg", + "singer_dress": "", + "singer_mic_cycle": "https://cos.xscmmidi.site/admin/ripple3695_17627709565119.svga", + "song_name": "公敌"*/ + private int id = 0; + private int room_id = 0; + private int user_id = 0; + private int singer_song_id = 0; + private int status = 0; + private int sort = 0; + private long createtime = 0; + private int boss_user_id = 0; + private String boss_nickname = ""; + private String boss_avatar = ""; + private String boss_dress = ""; + private String boss_mic_cycle = ""; + private int singer_user_id = 0; + private String singer_nickname = ""; + private String singer_avatar = ""; + private String singer_dress = ""; + private String singer_mic_cycle = ""; + private String song_name = ""; + } + +} diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/bean/SingerSongCount.kt b/BaseModule/src/main/java/com/xscm/moduleutil/bean/SingerSongCount.kt new file mode 100644 index 00000000..144f7215 --- /dev/null +++ b/BaseModule/src/main/java/com/xscm/moduleutil/bean/SingerSongCount.kt @@ -0,0 +1,40 @@ +package com.xscm.moduleutil.bean + +/** + * SingerSongCount 类,用于存储歌手和歌曲数量信息 + * 这个类可能用于统计或展示每位歌手的歌曲数量 + */ +class SingerSongCount { + // 类定义结束,这里可以添加属性和方法来存储和操作歌手及其歌曲数量 + + var total: Int = 0 + var today: Int = 0 + var yesterday: Int = 0 + var week: Int = 0 + var month: Int = 0 + var already: Int = 0 + + /* total + string + 总数 + 必需 + today + string + 今天 + 必需 + yesterday + string + 昨天 + 必需 + week + string + 本周 + 必需 + month + string + 本月 + 必需 + already + string + 已点*/ +} \ No newline at end of file diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/bean/SongPlaylist.kt b/BaseModule/src/main/java/com/xscm/moduleutil/bean/SongPlaylist.kt new file mode 100644 index 00000000..f86778d8 --- /dev/null +++ b/BaseModule/src/main/java/com/xscm/moduleutil/bean/SongPlaylist.kt @@ -0,0 +1,67 @@ +package com.xscm.moduleutil.bean + +class SongPlaylist { + + var count: Int = 0 + var lists: List = ArrayList() + + class SongPlaylistBean { + + var id: Int = 0 + var room_id :String ="" + var user_id: String = "" + var singer_song_id: String = "" + var status:String ="" + var sort: Int = 0 + var boss_nickname: String = "" + var song_name: String = "" + var gift_id: String = "" + var gift_num: String = "" + var createtime: String = "" + var gift_name: String = "" + var gift_price: String = "" + var base_image: String = "" + var singer_nickname: String = "" + + } + + /* id + string 列表ID + + user_id + string + 歌手ID + + song_name + string + 歌曲名 + + gift_id + string + 礼物ID + + gift_num + string + 礼物数量 + + createtime + string + 添加时间 + + gift_name + string + 礼物名称 + + gift_price + string + 礼物价格 + + base_image + string + 礼物图片 + + nickname + string + 歌手昵称*/ + +} \ No newline at end of file diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/bean/UserInfo.java b/BaseModule/src/main/java/com/xscm/moduleutil/bean/UserInfo.java index 7c381a25..e823f736 100644 --- a/BaseModule/src/main/java/com/xscm/moduleutil/bean/UserInfo.java +++ b/BaseModule/src/main/java/com/xscm/moduleutil/bean/UserInfo.java @@ -80,7 +80,8 @@ public class UserInfo extends BaseEvent implements Serializable { private String enter_image;//爵位飘屏的背景 private String enter_text;//爵位飘屏的文字 - + private int singer_status;//歌手认证状态0-待审核,1-通过,2-拒绝 -1:未认证 + private int singer_level;//歌手等级 // @Data diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/bean/room/EMMessageInfo.java b/BaseModule/src/main/java/com/xscm/moduleutil/bean/room/EMMessageInfo.java index b29ca5aa..0926eb5a 100644 --- a/BaseModule/src/main/java/com/xscm/moduleutil/bean/room/EMMessageInfo.java +++ b/BaseModule/src/main/java/com/xscm/moduleutil/bean/room/EMMessageInfo.java @@ -117,6 +117,15 @@ public class EMMessageInfo implements MultiItemEntity { ///移除红包 public static final int QXRoomMessageTypeQXRoomMessageRedRemove = 1061; + ///点歌房当前歌曲发生变化 + public static final int QXRoomMessageTypeSingerRoomCurrentSongDidChanged=1070; + + ///点歌房下一首歌曲发生变化 + public static final int QXRoomMessageTypeSingerRoomNextSongDidChanged=1071; + + //已点歌曲数量 + public static final int QXRoomMessageTypeSongerNum = 1072; + ///房间内换麦 public static final int QXRoomMessageTypehm = 1039; diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/bean/room/RoomInfoResp.java b/BaseModule/src/main/java/com/xscm/moduleutil/bean/room/RoomInfoResp.java index bf40d99f..05b3c5af 100644 --- a/BaseModule/src/main/java/com/xscm/moduleutil/bean/room/RoomInfoResp.java +++ b/BaseModule/src/main/java/com/xscm/moduleutil/bean/room/RoomInfoResp.java @@ -6,6 +6,8 @@ import java.io.Serializable; import java.util.List; import com.xscm.moduleutil.bean.NobilitDeatils; +import com.xscm.moduleutil.bean.SingerInfo; + import lombok.Data; /** @@ -34,6 +36,8 @@ public class RoomInfoResp implements Serializable { private int hour_ranking_open;//1:开启 0:关闭 private NobilitDeatils.NobilityInfo nobility_info; + private SingerInfo singer_info; + //弹出麦位操作弹出 public boolean isWheatManager() { diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/bean/room/RoomPitBean.java b/BaseModule/src/main/java/com/xscm/moduleutil/bean/room/RoomPitBean.java index 3619a561..00053540 100644 --- a/BaseModule/src/main/java/com/xscm/moduleutil/bean/room/RoomPitBean.java +++ b/BaseModule/src/main/java/com/xscm/moduleutil/bean/room/RoomPitBean.java @@ -29,7 +29,7 @@ public class RoomPitBean implements Serializable { */ private String id;//id - private String pit_number = "";//麦位号 + private String pit_number="";//麦位号 private String state;//麦位状态 正常 ,1封麦;3禁麦 private int is_lock;//0未锁麦 1锁麦 private int is_mute;//0未禁麦 1禁麦 @@ -69,4 +69,8 @@ public class RoomPitBean implements Serializable { private String nickname_color;//昵称颜色 private String mic_cycle;//麦圈 + + private boolean occupied; + private boolean imageType;//是否是演唱者 + } diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/enumType/QXRoomSeatViewType.java b/BaseModule/src/main/java/com/xscm/moduleutil/enumType/QXRoomSeatViewType.java index 2ce338f4..c33860b7 100644 --- a/BaseModule/src/main/java/com/xscm/moduleutil/enumType/QXRoomSeatViewType.java +++ b/BaseModule/src/main/java/com/xscm/moduleutil/enumType/QXRoomSeatViewType.java @@ -17,8 +17,10 @@ public enum QXRoomSeatViewType { * 拍卖麦位 */ AUCTION(2, "拍卖麦位"), - - + /** + * 点唱 + */ + JUKEBOX(9,"点唱麦位"), /** * 小黑屋麦位 @@ -30,6 +32,8 @@ public enum QXRoomSeatViewType { */ FRIEND(7, "交友房麦位"); + + private final int value; private final String description; diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/enumType/RoomType.kt b/BaseModule/src/main/java/com/xscm/moduleutil/enumType/RoomType.kt index a1cb8eb8..5f19c99c 100644 --- a/BaseModule/src/main/java/com/xscm/moduleutil/enumType/RoomType.kt +++ b/BaseModule/src/main/java/com/xscm/moduleutil/enumType/RoomType.kt @@ -14,8 +14,10 @@ enum class RoomType( AUCTION("拍卖(真爱拍小黑屋)", 2), DATING("交友", 1,3, 4, 8), // 1、3、4、8 均对应交友 BLACK_ROOM("小黑屋", 6), + JUKEBOX("点唱", 9), MUTUAL_ENTERTAINMENT("互娱", 7); + companion object { /** * 根据 type_id 字符串获取对应的枚举实例 diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/event/RoomGiftGiveEvent.java b/BaseModule/src/main/java/com/xscm/moduleutil/event/RoomGiftGiveEvent.java index 9606e381..b95233b2 100644 --- a/BaseModule/src/main/java/com/xscm/moduleutil/event/RoomGiftGiveEvent.java +++ b/BaseModule/src/main/java/com/xscm/moduleutil/event/RoomGiftGiveEvent.java @@ -31,6 +31,4 @@ public class RoomGiftGiveEvent extends BaseEvent { this.heart_id = heart_id; this.auction_id = auction_id; } - - } diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/http/ApiServer.java b/BaseModule/src/main/java/com/xscm/moduleutil/http/ApiServer.java index 491ac6ff..fc4157e6 100644 --- a/BaseModule/src/main/java/com/xscm/moduleutil/http/ApiServer.java +++ b/BaseModule/src/main/java/com/xscm/moduleutil/http/ApiServer.java @@ -128,6 +128,46 @@ public interface ApiServer { @GET(Constants.GET_TEMP_KEY) Call> getTempKey(); + @FormUrlEncoded + @POST(Constants.POST_SINGER_AUTH) + Call> singerAuth(@Field("song") String song); + + @FormUrlEncoded + @POST(Constants.POST_GET_SONG) + Call> getSong(@Field("user_id") String user_id,@Field("room_id") String room_id,@Field("page") String page, @Field("page_limit") String page_limit); + + @FormUrlEncoded + @POST(Constants.POST_SINGER_SONG_CUT) + Call> singerSongCut(@Field("id") String id); + + @FormUrlEncoded + @POST(Constants.POST_SINGER_SONG_TOP) + Call> singerSongTop(@Field("id") String id); + + @FormUrlEncoded + @POST(Constants.POST_SINGER_SONG_COUNT) + Call> singerSongCount(@Field("room_id") String room_id); + + @FormUrlEncoded + @POST(Constants.POST_SINGER_SONG) + Call> singerSong(@Field("song_id") String song_id,@Field("room_id") String room_id); + + @FormUrlEncoded + @POST(Constants.POST_SINGER_SONG_LIST) + Call> singerSongList(@Field("room_id") String room_id,@Field("type") String type,@Field("page") String page, @Field("page_limit") String page_limit); + + @FormUrlEncoded + @POST(Constants.POST_SINGER_DELETE_SONG) + Call> deleteSong(@Field("id") String song_id); + + @FormUrlEncoded + @POST(Constants.POST_SINGER_ADD_SONG) + Call> singerAddSong(@Field("song_name") String song_name,@Field("gift_id") String gift_id,@Field("gift_num") String gift_num); + + @FormUrlEncoded + @POST(Constants.POST_SINGER_UPDATE_SONG) + Call> singerUpdateSong(@Field("id") String is,@Field("song_name") String song_name,@Field("gift_id") String gift_id,@Field("gift_num") String gift_num); + @FormUrlEncoded @POST(Constants.POST_ROOM_RANK) Call>> getRoomRank(@Field("room_id") String room_id, @Field("type") String type, @Field("time_type") String time_type, @Field("page") String page, @Field("page_limit") String page_limit); diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/http/RetrofitClient.java b/BaseModule/src/main/java/com/xscm/moduleutil/http/RetrofitClient.java index 7b59917c..77922626 100644 --- a/BaseModule/src/main/java/com/xscm/moduleutil/http/RetrofitClient.java +++ b/BaseModule/src/main/java/com/xscm/moduleutil/http/RetrofitClient.java @@ -510,6 +510,236 @@ public class RetrofitClient { }); } + public void singerAuth(String url, BaseObserver observer) { + sApiServer.singerAuth(url).enqueue(new Callback>() { + + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200) { + BaseModel baseModel = response.body(); + if (baseModel.getCode() == 1) + observer.onNext(baseModel.getMsg()); + else if (baseModel.getCode() == 301) { + try { + ToastUtils.showShort(baseModel.getMsg()); + CommonAppContext.getInstance().clearLoginInfo(); + } catch (ClassNotFoundException e) { + } + } else { + observer.onNext(baseModel.getMsg()); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + LogUtils.e("认证失败", t.fillInStackTrace()); + } + }); + + } + + public void getSong(String userid, String roomId, String page, String pagaeSice, BaseObserver observer) { + sApiServer.getSong(userid, roomId, page, pagaeSice).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200) { + BaseModel baseModel = response.body(); + if (baseModel.getCode() == 1) { + observer.onNext(baseModel.getData()); + } else if (baseModel.getCode() == 301) { + try { + ToastUtils.showShort(baseModel.getMsg()); + CommonAppContext.getInstance().clearLoginInfo(); + } catch (ClassNotFoundException e) { + } + } else { + ToastUtils.showShort(baseModel.getMsg()); + observer.onNext(baseModel.getData()); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + LogUtils.e("获取歌曲失败", t.fillInStackTrace()); + } + + }); + } + + public void singerSongCut(String id,BaseObserver observer) { + sApiServer.singerSongCut(id).enqueue(new Callback>() { + + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200) { + BaseModel baseModel = response.body(); + if (baseModel.getCode() == 1) { + ToastUtils.showShort(baseModel.getMsg()); + } else if (baseModel.getCode() == 301) { + try { + ToastUtils.showShort(baseModel.getMsg()); + CommonAppContext.getInstance().clearLoginInfo(); + } catch (ClassNotFoundException e) { + } + } else { + ToastUtils.showShort(baseModel.getMsg()); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + + } + }); + } + + public void singerSongTop(String id,BaseObserver observer){ + sApiServer.singerSongTop(id).enqueue(new Callback>() { + + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200) { + BaseModel baseModel = response.body(); + if (baseModel.getCode() == 1) { + ToastUtils.showShort(baseModel.getMsg()); + observer.onNext(baseModel.getMsg()); + } else if (baseModel.getCode() == 301) { + try { + ToastUtils.showShort(baseModel.getMsg()); + CommonAppContext.getInstance().clearLoginInfo(); + } catch (ClassNotFoundException e) { + } + } else { + observer.onNext(baseModel.getMsg()); + ToastUtils.showShort(baseModel.getMsg()); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + LogUtils.e("获取歌曲失败", t.fillInStackTrace()); + } + }); + } + + public void singerSongCount(String roomId,BaseObserver observer){ + sApiServer.singerSongCount(roomId).enqueue(new Callback>(){ + + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200) { + BaseModel baseModel = response.body(); + if (baseModel.getCode() == 1) { + observer.onNext(baseModel.getData()); + } else if (baseModel.getCode() == 301) { + try { + ToastUtils.showShort(baseModel.getMsg()); + CommonAppContext.getInstance().clearLoginInfo(); + } catch (ClassNotFoundException e) { + + } + }else { + ToastUtils.showShort(baseModel.getMsg()); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + LogUtils.e("获取歌曲数量失败", t.fillInStackTrace()); + } + }); + } + + public void singerSong(String songId, String roomId, BaseObserver observer) { + sApiServer.singerSong(songId, roomId).enqueue(new Callback>() { + + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200) { + BaseModel baseModel = response.body(); + if (baseModel.getCode() == 1) { + ToastUtils.showShort(baseModel.getMsg()); + } else if (baseModel.getCode() == 301) { + try { + ToastUtils.showShort(baseModel.getMsg()); + CommonAppContext.getInstance().clearLoginInfo(); + } catch (ClassNotFoundException e) { + } + } else { + ToastUtils.showShort(baseModel.getMsg()); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + LogUtils.e("singerSong", t.fillInStackTrace()); + } + }); + } + + public void singerSongList(String room_id, String type, String page, String page_limit, BaseObserver observer) { + sApiServer.singerSongList(room_id, type, page, page_limit).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200) { + BaseModel baseModel = response.body(); + if (baseModel.getCode() == 1) { + observer.onNext(baseModel.getData()); + } else if (baseModel.getCode() == 301) { + try { + ToastUtils.showShort(baseModel.getMsg()); + CommonAppContext.getInstance().clearLoginInfo(); + } catch (ClassNotFoundException e) { + + } + } else { + ToastUtils.showShort(baseModel.getMsg()); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + LogUtils.e("获取歌曲失败", t.fillInStackTrace()); + } + }); + } + + public void deleteSong(String songId, BaseObserver observer) { + sApiServer.deleteSong(songId).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200) { + BaseModel baseModel = response.body(); + if (baseModel.getCode() == 1) { + observer.onNext(baseModel.getData()); + } else if (baseModel.getCode() == 301) { + try { + ToastUtils.showShort(baseModel.getMsg()); + CommonAppContext.getInstance().clearLoginInfo(); + } catch (ClassNotFoundException e) { + } + } else { + ToastUtils.showShort(baseModel.getMsg()); + observer.onNext(baseModel.getData()); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + LogUtils.e("获取歌曲失败", t.fillInStackTrace()); + } + + }); + } + public void getTempKey(BaseObserver observer) { sApiServer.getTempKey().enqueue(new Callback>() { @Override @@ -610,10 +840,9 @@ public class RetrofitClient { sApiServer.roomRanking(type).compose(new DefaultTransformer<>()).subscribe(observer); } else if (ranking_type.equals("1") || ranking_type.equals("2")) { sApiServer.wealthRanking(ranking_type, type).compose(new DefaultTransformer<>()).subscribe(observer); - }else if (ranking_type.equals("3")) { + } else if (ranking_type.equals("3")) { sApiServer.loveRanking(type).compose(new DefaultTransformer<>()).subscribe(observer); - } - else if (ranking_type.equals("4")) { + } else if (ranking_type.equals("4")) { sApiServer.guildRanking().compose(new DefaultTransformer<>()).subscribe(observer); } } @@ -1420,7 +1649,7 @@ public class RetrofitClient { }); } - public void getBanners(String s,BaseObserver> observer) { + public void getBanners(String s, BaseObserver> observer) { sApiServer.getBanners(s).enqueue(new Callback>>() { @Override public void onResponse(Call>> call, Response>> response) { @@ -1569,6 +1798,70 @@ public class RetrofitClient { @Override public void onFailure(Call>> call, Throwable t) { + t.fillInStackTrace(); + } + }); + } + + public void singerUpdateSong(String songId, String song_name, String gift_id, String gift_num, BaseObserver observer) { + sApiServer.singerUpdateSong(songId, song_name, gift_id, gift_num).enqueue(new Callback>() { + + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200) { + BaseModel listBaseModel = response.body(); + if (listBaseModel.getCode() == 1) { + ToastUtils.showLong(listBaseModel.getMsg()); + observer.onNext(listBaseModel.getData()); + } else if (listBaseModel.getCode() == 0) { + ToastUtils.showLong(listBaseModel.getMsg()); + observer.onNext(null); + } else if (listBaseModel.getCode() == 301) { + try { + CommonAppContext.getInstance().clearLoginInfo(); + ToastUtils.showShort(listBaseModel.getMsg()); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + + } + }); + } + + public void singerAddSong(String song_name, String gift_id, String gift_num, BaseObserver observer) { + sApiServer.singerAddSong(song_name, gift_id, gift_num).enqueue(new Callback>() { + + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200) { + BaseModel listBaseModel = response.body(); + if (listBaseModel.getCode() == 1) { + ToastUtils.showLong(listBaseModel.getMsg()); + observer.onNext(listBaseModel.getData()); + } else if (listBaseModel.getCode() == 0) { + ToastUtils.showLong(listBaseModel.getMsg()); + observer.onNext(null); + } else if (listBaseModel.getCode() == 301) { + try { + CommonAppContext.getInstance().clearLoginInfo(); + ToastUtils.showShort(listBaseModel.getMsg()); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + } + } + + @Override + public void onFailure(Call> call, Throwable t) { } }); @@ -1928,7 +2221,7 @@ public class RetrofitClient { public void onFailure(Call> call, Throwable t) { MessageListenerSingleton.getInstance().quitGroup(roomId); CommonAppContext.getInstance().isRoomJoininj = false; - observer.onError( t); + observer.onError(t); } }); } @@ -2144,8 +2437,8 @@ public class RetrofitClient { // }); } - public void appPay(String user_id, String money, String coin, String type, String type_params, String type_id,String nobility_id, BaseObserver observer) { - sApiServer.appPay(user_id, money, coin, type, type_params, type_id,nobility_id).enqueue(new Callback>() { + public void appPay(String user_id, String money, String coin, String type, String type_params, String type_id, String nobility_id, BaseObserver observer) { + sApiServer.appPay(user_id, money, coin, type, type_params, type_id, nobility_id).enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { if (response.code() == 200) { @@ -2963,8 +3256,7 @@ public class RetrofitClient { }); } - public void setLockPit(String roomId, String pitNumber, String - isLock, BaseObserver observer) { + public void setLockPit(String roomId, String pitNumber, String isLock, BaseObserver observer) { sApiServer.setLockPit(roomId, pitNumber, isLock).enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { @@ -3020,11 +3312,13 @@ public class RetrofitClient { }); } + + public void agreeSong(String room_id, String type, BaseObserver observer) { sApiServer.agreeSong(room_id, type).enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { - LogUtils.e("练歌房","练歌房:"+response.body().toString()); + LogUtils.e("练歌房", "练歌房:" + response.body().toString()); onNextRetu(response, observer); } @@ -3401,7 +3695,8 @@ public class RetrofitClient { } }); } - public void getModifyHideStatus(String hide_status, BaseObserver observer ){ + + public void getModifyHideStatus(String hide_status, BaseObserver observer) { sApiServer.getModifyHideStatus(hide_status).enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { @@ -3414,6 +3709,7 @@ public class RetrofitClient { } }); } + public void getPostData(String new_password, String mobile, String code, String userId, BaseObserver observer) { sApiServer.getPostData(new_password, mobile, code, userId).enqueue(new Callback>() { @Override @@ -3755,7 +4051,7 @@ public class RetrofitClient { if (string != null) { int code = string.getCode(); if (code == 1) { - observer.onNext(string.getMsg()!= null ? string.getMsg() : ""); + observer.onNext(string.getMsg() != null ? string.getMsg() : ""); } else if (code == 301) { try { @@ -3815,22 +4111,22 @@ public class RetrofitClient { } - public void sendAppLog(String logName,String logPath,BaseObserver observer) { - sApiServer.postSendAppLog(logName,logPath).enqueue(new Callback>() { + public void sendAppLog(String logName, String logPath, BaseObserver observer) { + sApiServer.postSendAppLog(logName, logPath).enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { if (response.code() == 200) { int code = response.body().getCode(); if (code == 1) { observer.onNext("成功"); - }else if (code == 301){ + } else if (code == 301) { try { ToastUtils.showShort(response.body().getMsg()); CommonAppContext.getInstance().clearLoginInfo(); } catch (ClassNotFoundException e) { - LogUtils.e( e.toString()); + LogUtils.e(e.toString()); } - }else { + } else { observer.onNext("失败"); } } @@ -3996,7 +4292,7 @@ public class RetrofitClient { }); } - public void getNobilityDetail(BaseObserver observer){ + public void getNobilityDetail(BaseObserver observer) { sApiServer.getNobilityDetail().enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { @@ -4004,9 +4300,9 @@ public class RetrofitClient { BaseModel baseModel = response.body(); if (baseModel.getCode() == 1) { observer.onNext(baseModel.getData()); - }else if (baseModel.getCode() == 0){ + } else if (baseModel.getCode() == 0) { ToastUtils.showShort(baseModel.getMsg()); - }else if (baseModel.getCode() == 301){ + } else if (baseModel.getCode() == 301) { try { ToastUtils.showShort(baseModel.getMsg()); CommonAppContext.getInstance().clearLoginInfo(); @@ -4015,6 +4311,7 @@ public class RetrofitClient { } } } + @Override public void onFailure(Call> call, Throwable t) { t.printStackTrace(); @@ -4023,7 +4320,7 @@ public class RetrofitClient { } - public void getNobilityList(BaseObserver> observer){ + public void getNobilityList(BaseObserver> observer) { sApiServer.getNobilityList().enqueue(new Callback>>() { @Override public void onResponse(Call>> call, Response>> response) { @@ -4031,9 +4328,9 @@ public class RetrofitClient { BaseModel> baseModel = response.body(); if (baseModel.getCode() == 1) { observer.onNext(baseModel.getData()); - }else if (baseModel.getCode() == 0){ + } else if (baseModel.getCode() == 0) { ToastUtils.showShort(baseModel.getMsg()); - }else if (baseModel.getCode() == 301){ + } else if (baseModel.getCode() == 301) { try { ToastUtils.showShort(baseModel.getMsg()); CommonAppContext.getInstance().clearLoginInfo(); @@ -4050,7 +4347,7 @@ public class RetrofitClient { }); } - public void getNobilityPrice(String id, BaseObserver observer){ + public void getNobilityPrice(String id, BaseObserver observer) { sApiServer.getNobilityPrice(id).enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { @@ -4058,9 +4355,9 @@ public class RetrofitClient { BaseModel baseModel = response.body(); if (baseModel.getCode() == 1) { observer.onNext(baseModel.getData()); - }else if (baseModel.getCode() == 0){ + } else if (baseModel.getCode() == 0) { ToastUtils.showShort(baseModel.getMsg()); - }else if (baseModel.getCode() == 301){ + } else if (baseModel.getCode() == 301) { try { ToastUtils.showShort(baseModel.getMsg()); CommonAppContext.getInstance().clearLoginInfo(); diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/widget/Constants.java b/BaseModule/src/main/java/com/xscm/moduleutil/widget/Constants.java index fff2a341..20ffdc2a 100644 --- a/BaseModule/src/main/java/com/xscm/moduleutil/widget/Constants.java +++ b/BaseModule/src/main/java/com/xscm/moduleutil/widget/Constants.java @@ -411,6 +411,16 @@ public class Constants { public static final String GET_NOBILITY_DETAIL = "/api/Nobility/get_nobility_detail";//爵位详情 public static final String GET_NOBILITY_LIST = "/api/Nobility/get_nobility_list";//爵位列表 public static final String GET_NOBILITY_PRICE = "/api/Nobility/get_nobility_price";//爵位购买价格 + public static final String POST_SINGER_AUTH = "/api/SingerSong/singerAuth";//歌手认证 + public static final String POST_GET_SONG = "/api/SingerSong/getSong";//获取用户的歌单 + public static final String POST_SINGER_SONG = "/api/SingerSong/singerSong";//点歌 + public static final String POST_SINGER_SONG_TOP = "/api/SingerSong/singerSongTop";//歌曲置顶 + public static final String POST_SINGER_SONG_COUNT = "/api/SingerSong/singerSongCount";//点歌各类型各个总数 + public static final String POST_SINGER_SONG_LIST = "/api/SingerSong/singerSongList";//点歌列表 + public static final String POST_SINGER_SONG_CUT = "/api/SingerSong/singerSongCut";//切歌 + public static final String POST_SINGER_ADD_SONG = "/api/SingerSong/singerAddSong";//歌手添加歌曲 + public static final String POST_SINGER_DELETE_SONG = "/api/SingerSong/singerDelSong";//歌手删除 歌曲 + public static final String POST_SINGER_UPDATE_SONG = "/api/SingerSong/singerEditSong";//歌手修改歌曲 public static final String POST_SEND_LOG = "api/Report/android_log_report";//上传log信息 diff --git a/BaseModule/src/main/res/drawable/bg_r14_1b1926.xml b/BaseModule/src/main/res/drawable/bg_r14_1b1926.xml new file mode 100644 index 00000000..5a0f259a --- /dev/null +++ b/BaseModule/src/main/res/drawable/bg_r14_1b1926.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/BaseModule/src/main/res/drawable/bg_r16_2b2935.xml b/BaseModule/src/main/res/drawable/bg_r16_2b2935.xml new file mode 100644 index 00000000..3038e349 --- /dev/null +++ b/BaseModule/src/main/res/drawable/bg_r16_2b2935.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/BaseModule/src/main/res/drawable/bg_r16_3abc6d.xml b/BaseModule/src/main/res/drawable/bg_r16_3abc6d.xml new file mode 100644 index 00000000..830498f5 --- /dev/null +++ b/BaseModule/src/main/res/drawable/bg_r16_3abc6d.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/BaseModule/src/main/res/drawable/bg_r34_3abc6d.xml b/BaseModule/src/main/res/drawable/bg_r34_3abc6d.xml new file mode 100644 index 00000000..9dae300f --- /dev/null +++ b/BaseModule/src/main/res/drawable/bg_r34_3abc6d.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/BaseModule/src/main/res/drawable/bg_r53_73040404.xml b/BaseModule/src/main/res/drawable/bg_r53_73040404.xml new file mode 100644 index 00000000..46705d73 --- /dev/null +++ b/BaseModule/src/main/res/drawable/bg_r53_73040404.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/BaseModule/src/main/res/drawable/bg_r8_262431.xml b/BaseModule/src/main/res/drawable/bg_r8_262431.xml new file mode 100644 index 00000000..d130d315 --- /dev/null +++ b/BaseModule/src/main/res/drawable/bg_r8_262431.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/BaseModule/src/main/res/layout/fragment_comment_dialog.xml b/BaseModule/src/main/res/layout/fragment_comment_dialog.xml index 3b97a6f6..3a5ff799 100644 --- a/BaseModule/src/main/res/layout/fragment_comment_dialog.xml +++ b/BaseModule/src/main/res/layout/fragment_comment_dialog.xml @@ -21,7 +21,7 @@ android:gravity="center|left" android:layout_margin="@dimen/dp_16" android:layout_marginTop="@dimen/dp_12" - android:text="全部评论(56)" + tools:text="全部评论(56)" android:textColor="@color/color_FF333333" android:textSize="@dimen/sp_16" android:textStyle="bold" /> diff --git a/BaseModule/src/main/res/values/styles.xml b/BaseModule/src/main/res/values/styles.xml index 78195702..e9a01453 100644 --- a/BaseModule/src/main/res/values/styles.xml +++ b/BaseModule/src/main/res/values/styles.xml @@ -325,6 +325,11 @@ + \ No newline at end of file diff --git a/MainModule/src/main/AndroidManifest.xml b/MainModule/src/main/AndroidManifest.xml index 801888ef..c3c2bdf7 100644 --- a/MainModule/src/main/AndroidManifest.xml +++ b/MainModule/src/main/AndroidManifest.xml @@ -3,11 +3,15 @@ - - + + + @@ -17,16 +21,12 @@ - - - - - - - - - - - @@ -165,27 +158,24 @@ - + android:exported="false" /> + android:exported="false" /> + android:exported="false" /> - - + android:exported="false" /> - + @@ -196,7 +186,6 @@ - - - (), private val imSdkListener = object : V2TIMSDKListener() { override fun onConnecting() {} + /** + * 重连成功的回调处理函数 + * 当网络连接成功建立时,此方法会被调用 + * 如果存在有效的播放ID,则执行重连操作 + */ override fun onConnectSuccess() { //重连成功 + // 检查当前是否有有效的播放ID if (CommonAppContext.getInstance().playId != null) { + // 输出重连成功的日志信息 LogUtils.e("@@@", "重连成功") + // 输出当前的播放ID信息 LogUtils.e("@@@", "" + CommonAppContext.getInstance().playId) + // 调用RetrofitClient执行房间用户重连操作 RetrofitClient.getInstance() .roomUserReconnect(CommonAppContext.getInstance().playId) } @@ -1021,6 +1031,17 @@ class RoomActivity : BaseMvpActivity(), } } + fun getRoomInfoResp(): List? { + val roomPitBeans = mRoomInfoResp?.room_info?.pit_list.orEmpty().filter { + it.user_id != null && it.user_id != "0" && it.user_id.isNotEmpty()&& it.user_id.toInt() != SpUtil.getUserId() + } + return roomPitBeans.ifEmpty { null } + } + + fun getRoomIds(): String? { + return roomId + } + // TODO: 发红包 fun redDialogView() { @@ -1385,7 +1406,7 @@ class RoomActivity : BaseMvpActivity(), handleMsgType1034(messageEvent, text) } else if (msgType == EMMessageInfo.QXRoomMessageTypeRoomTypeDidChanged) { handleMsgType1016(messageEvent, text) - } else if (msgType == EMMessageInfo.QXRoomMessageTypehm) { + } else if (msgType == EMMessageInfo.QXRoomMessageTypehm) {//房间内换麦 handleMsgType1039(messageEvent, text) } else if (msgType == EMMessageInfo.QXRoomMessageTypeRoomIsHostvalue) { roomFragment!!.handleMsgType1028(messageEvent) @@ -1447,9 +1468,17 @@ class RoomActivity : BaseMvpActivity(), qxRedPacketManager!!.addRedPacket(messageEvent.text.redpacketInfo) } else if (msgType == EMMessageInfo.QXRoomMessageTypeQXRoomMessageRedRemove) { qxRedPacketManager!!.removeRedPacket(messageEvent.text.redpacket_id) + } else if (msgType == EMMessageInfo.QXRoomMessageTypeSongerNum //房间点歌数量变化 + || msgType ==EMMessageInfo.QXRoomMessageTypeSingerRoomCurrentSongDidChanged //点歌房当前歌曲发生变化 + ||msgType == EMMessageInfo.QXRoomMessageTypeSingerRoomNextSongDidChanged) { //点歌房下一首歌曲发生变化 + if (mRoomInfoResp != null && mRoomInfoResp!!.room_info != null) { + roomFragment!!.handleRoomMessage(messageEvent) + } } } + + private var endTime: Long = 0 private fun xlhDjs(endTimeStr: String?) { @@ -1724,6 +1753,13 @@ class RoomActivity : BaseMvpActivity(), roomFragment!!.handleRoomMessage(messageEvent) } + RoomType.JUKEBOX -> { + mBinding!!.rlMore.visibility = View.GONE + mBinding!!.rlMisc.visibility = View.GONE + + roomFragment?.handleRoomMessage(messageEvent) + } + else -> { roomFragment!!.updateSeatViewExchangedWithPitArray(mRoomInfoResp) } @@ -2359,16 +2395,16 @@ class RoomActivity : BaseMvpActivity(), mBinding!!.ivBg.setImageDrawable(resources.getDrawable(bjId)) } - fun setvisibTop(`is`: Boolean) { - mBinding!!.roomTop.root.visibility = - if (`is`) View.VISIBLE else View.GONE - } - fun setOnlineNumber(number: Int) { this.number = number mBinding!!.roomTop.tvNum.text = number.toString() } + fun setvisibTop(`is`: Boolean) { + mBinding!!.roomTop.root.visibility = + if (`is`) View.VISIBLE else View.GONE + } + fun setUserInfo() { mRoomInfoResp!!.user_info.is_collect = 1 mBinding!!.roomTop.btnFollow.background = @@ -3713,6 +3749,8 @@ class RoomActivity : BaseMvpActivity(), maxHeightDp = 453 } else if (mRoomInfoResp!!.room_info.type_id == "7") { maxHeightDp = 373 + } else if (mRoomInfoResp!!.room_info.type_id == "9") { + maxHeightDp = 373 } adjustLayoutHeights() } @@ -3761,6 +3799,12 @@ class RoomActivity : BaseMvpActivity(), QXRoomSeatViewType.CABIN } + RoomType.JUKEBOX -> { + changeBackgroundColor(mRoomInfoResp!!.room_info.room_background) + setvisibTop(true) + QXRoomSeatViewType.JUKEBOX + } + null -> { LogUtils.e("@@@", "RoomType is null") QXRoomSeatViewType.NONE diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/RequestSongPagerAdapter.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/RequestSongPagerAdapter.java new file mode 100644 index 00000000..ddec8bab --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/RequestSongPagerAdapter.java @@ -0,0 +1,42 @@ +package com.xscm.modulemain.activity.room.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.viewpager2.adapter.FragmentStateAdapter; + +import com.xscm.modulemain.activity.room.fragment.RequestedSongsFragment; +import com.xscm.modulemain.activity.room.fragment.SongHistoryFragment; +import com.xscm.modulemain.activity.room.fragment.SongRequestFragment; + +/** + * 点歌页面ViewPager适配器 + */ +public class RequestSongPagerAdapter extends FragmentStateAdapter { + + private static final int TAB_COUNT = 3; // 三个标签页 + + public RequestSongPagerAdapter(@NonNull FragmentActivity fragmentActivity) { + super(fragmentActivity); + } + + @NonNull + @Override + public Fragment createFragment(int position) { + switch (position) { + case 0: + return new SongRequestFragment(); // 点歌页面 + case 1: + return new RequestedSongsFragment(); // 已点歌曲页面 + case 2: + return new SongHistoryFragment(); // 历史记录页面 + default: + return new SongRequestFragment(); + } + } + + @Override + public int getItemCount() { + return TAB_COUNT; + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/RequestedSongsAdapter.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/RequestedSongsAdapter.java new file mode 100644 index 00000000..8e0107e1 --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/RequestedSongsAdapter.java @@ -0,0 +1,209 @@ + +package com.xscm.modulemain.activity.room.adapter; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.xscm.modulemain.databinding.ItemRequestedSongBinding; +import com.xscm.moduleutil.bean.SongPlaylist; +import com.xscm.moduleutil.utils.ImageUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * 已点歌曲列表适配器 + */ +public class RequestedSongsAdapter extends RecyclerView.Adapter { + + // 歌曲状态常量 + public static final int STATUS_PLAYING = 1; // 正在播放 + public static final int STATUS_PENDING = 2; // 等待播放 + public static final int STATUS_TOP = 3; // 置顶 + + // 列表项类型 + private static final int TYPE_NORMAL = 0; // 普通列表项 + private static final int TYPE_FOOTER = 1; // 底部加载更多项 + + private List songList = new ArrayList<>(); + private boolean isShowFooter = false; // 是否显示底部加载更多 + + private OnItemClickListener onItemClickListener; + + public interface OnItemClickListener { + void onPlayClick(SongPlaylist.SongPlaylistBean song, int position); + + void onTopClick(SongPlaylist.SongPlaylistBean song, int position); + } + + public void setOnItemClickListener(OnItemClickListener listener) { + this.onItemClickListener = listener; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + // 创建普通列表项视图 + ItemRequestedSongBinding binding = ItemRequestedSongBinding.inflate( + LayoutInflater.from(parent.getContext()), parent, false); + return new SongViewHolder(binding); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof FooterViewHolder) { + // 底部加载更多项,不需要处理 + return; + } + + if (holder instanceof SongViewHolder) { + // 普通列表项 + SongViewHolder songHolder = (SongViewHolder) holder; + + // 检查位置是否有效,防止索引越界 + if (position >= songList.size()) { + return; + } + + SongPlaylist.SongPlaylistBean song = songList.get(position); + + // 设置歌曲信息 + songHolder.binding.tvSongName.setText(song.getSong_name()); + ImageUtils.loadHead(song.getBase_image(), songHolder.binding.ivSongCover); + songHolder.binding.tvSinger.setText("演唱者:" + song.getSinger_nickname()); + songHolder.binding.tvRequestBos.setText("老板:" + song.getBoss_nickname()); + + // 根据位置显示不同的UI + if (position == 0) { + // 第一个是正在播放 + songHolder.binding.tvRequestStatus.setText("正在播放"); + songHolder.binding.tvRequestStatus.setTextColor(0xFF3ABC6D); + songHolder.binding.tvRequestStatus.setBackgroundColor(android.graphics.Color.TRANSPARENT); + } else { + // 第三个以后都是置顶,文字是白色的 + songHolder.binding.tvRequestStatus.setText("置顶"); + songHolder.binding.tvRequestStatus.setTextColor(0xFFFFFFFF); + songHolder.binding.tvRequestStatus.setBackgroundResource(com.xscm.moduleutil.R.drawable.bg_r34_3abc6d); + } + + + // 设置tvRequestStatus的点击事件,只有置顶状态才能点击 + songHolder.binding.tvRequestStatus.setOnClickListener(v -> { + // 只有第三个及以后的项目(position > 1)才能点击tvRequestStatus + if (position > 1 && onItemClickListener != null) { + onItemClickListener.onTopClick(song, position); + } + }); + } + } + + @Override + public int getItemViewType(int position) { + // 如果是最后一项且需要显示底部加载更多,则返回底部类型 + if (position == songList.size() && isShowFooter) { + return TYPE_FOOTER; + } + return TYPE_NORMAL; + } + + @Override + public int getItemCount() { + // 如果需要显示底部加载更多,则数量加1 + return songList.size() + (isShowFooter ? 1 : 0); + } + + /** + * 根据歌曲对象获取状态 + */ + private int getStatusFromSong(SongPlaylist.SongPlaylistBean song) { + // 根据业务逻辑判断状态,这里仅作为示例 + if ("1".equals(song.getStatus())) { + return STATUS_PLAYING; + } else if ("0".equals(song.getStatus())) { + return STATUS_TOP; + } else { + return STATUS_PENDING; + } + } + + /** + * 设置歌曲列表 + */ + public void setSongList(List list) { + if (list != null) { + this.songList.clear(); + this.songList.addAll(list); + notifyDataSetChanged(); + } + } + + /** + * 添加歌曲列表(用于加载更多) + */ + public void addSongList(List list) { + if (list != null) { + int startPos = this.songList.size(); + this.songList.addAll(list); + notifyItemRangeInserted(startPos, list.size()); + } + } + + /** + * 显示或隐藏底部加载更多 + */ + public void setShowFooter(boolean showFooter) { + boolean wasShowing = this.isShowFooter; + this.isShowFooter = showFooter; + + if (wasShowing != showFooter) { + if (showFooter) { + notifyItemInserted(songList.size()); + } else { + notifyItemRemoved(songList.size()); + } + } + } + + /** + * 清空列表 + */ + public void clear() { + this.songList.clear(); + notifyDataSetChanged(); + } + + /** + * 获取指定位置的歌曲 + */ + public SongPlaylist.SongPlaylistBean getItem(int position) { + if (position >= 0 && position < songList.size()) { + return songList.get(position); + } + return null; + } + + /** + * 普通列表项ViewHolder + */ + static class SongViewHolder extends RecyclerView.ViewHolder { + ItemRequestedSongBinding binding; + + public SongViewHolder(@NonNull ItemRequestedSongBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } + + /** + * 底部加载更多ViewHolder + */ + static class FooterViewHolder extends RecyclerView.ViewHolder { + public FooterViewHolder(@NonNull View itemView) { + super(itemView); + } + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/RoomJukeboxAdapter.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/RoomJukeboxAdapter.java new file mode 100644 index 00000000..4a7a5304 --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/RoomJukeboxAdapter.java @@ -0,0 +1,39 @@ +package com.xscm.modulemain.activity.room.adapter; + +import androidx.annotation.NonNull; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.BaseViewHolder; +import com.xscm.modulemain.R; +import com.xscm.modulemain.view.RoomJukeboxWheatView; +import com.xscm.moduleutil.bean.room.RoomPitBean; + +public class RoomJukeboxAdapter extends BaseQuickAdapter { + private OnWheatClickListener listener; + + public interface OnWheatClickListener { + void onWheatClick( RoomJukeboxWheatView roomJukeboxWheatView,int position); + } + + + public void setOnWheatClickListener(OnWheatClickListener listener) { + this.listener = listener; + } + public RoomJukeboxAdapter(int layoutResId) { + super(layoutResId); + } + + @Override + protected void convert(@NonNull BaseViewHolder helper, RoomPitBean item) { + RoomJukeboxWheatView roomJukeboxWheatView= helper.getView(R.id.wheatView); + // 确保pitNumber与数据匹配,而不是使用位置 + roomJukeboxWheatView.setRoomWheatNumber(item.getPit_number()); + roomJukeboxWheatView.setData(item); + + roomJukeboxWheatView.setOnClickListener(v -> { + if (listener != null) { + listener.onWheatClick(roomJukeboxWheatView,helper.getLayoutPosition()); + } + }); + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/SongAdapter.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/SongAdapter.java new file mode 100644 index 00000000..f1c33a5a --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/SongAdapter.java @@ -0,0 +1,103 @@ + +package com.xscm.modulemain.activity.room.adapter; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.xscm.modulemain.R; +import com.xscm.moduleutil.bean.SongPlaylist; + +import java.util.ArrayList; +import java.util.List; + +/** + * 歌曲列表适配器 + */ +public class SongAdapter extends RecyclerView.Adapter { + + private List songList = new ArrayList<>(); + private OnSongClickListener onSongClickListener; + + public SongAdapter(List songList) { + this.songList = songList; + } + + public void setSongList(List songList) { + this.songList = songList; + notifyDataSetChanged(); + } + + public void setOnSongClickListener(OnSongClickListener listener) { + this.onSongClickListener = listener; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_song, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + SongPlaylist.SongPlaylistBean song = songList.get(position); + + // 设置歌曲信息 + holder.tvSongName.setText(song.getSong_name()); + holder.tvSongSinger.setText("演唱者:" + song.getSinger_nickname()); + + // 设置礼物信息 + holder.tvGiftName.setText(song.getGift_name()+"*"+song.getGift_num()); + holder.tvGiftPrice.setText(song.getGift_price()); + + // 加载礼物图片 + Glide.with(holder.itemView.getContext()) + .load(song.getBase_image()) + .into(holder.ivGiftImage); + + // 设置状态 + holder.tvGiftStatus.setText("点歌"); + + // 设置点击事件 + holder.itemView.setOnClickListener(v -> { + if (onSongClickListener != null) { + onSongClickListener.onSongClick(song, position); + } + }); + } + + @Override + public int getItemCount() { + return songList.size(); + } + + static class ViewHolder extends RecyclerView.ViewHolder { + TextView tvSongName; + TextView tvSongSinger; + ImageView ivGiftImage; + TextView tvGiftName; + TextView tvGiftPrice; + TextView tvGiftStatus; + + public ViewHolder(@NonNull View itemView) { + super(itemView); + tvSongName = itemView.findViewById(R.id.tv_song_name); + tvSongSinger = itemView.findViewById(R.id.tv_song_singer); + ivGiftImage = itemView.findViewById(R.id.iv_gift_image); + tvGiftName = itemView.findViewById(R.id.tv_gift_name); + tvGiftPrice = itemView.findViewById(R.id.tv_gift_price); + tvGiftStatus = itemView.findViewById(R.id.tv_gift_status); + } + } + + public interface OnSongClickListener { + void onSongClick(SongPlaylist.SongPlaylistBean song, int position); + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/SongHistoryAdapter.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/SongHistoryAdapter.java new file mode 100644 index 00000000..c52a92e1 --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/SongHistoryAdapter.java @@ -0,0 +1,47 @@ +package com.xscm.modulemain.activity.room.adapter; + +import androidx.annotation.NonNull; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.BaseViewHolder; +import com.xscm.modulemain.R; +import com.xscm.moduleutil.bean.SongPlaylist; +import com.xscm.moduleutil.utils.ImageUtils; + + +/** + * 歌曲历史记录适配器 + * 继承自BaseQuickAdapter,用于展示歌曲播放历史列表 + * + */ +public class SongHistoryAdapter extends BaseQuickAdapter { + /** + * 构造函数 + * 初始化适配器,设置历史记录项的布局文件 + */ + public SongHistoryAdapter() { + super(R.layout.item_history); + } + + /** + * 方法:将数据绑定到视图 + * + * @param helper ViewHolder对象,用于获取视图组件 + * @param item 当前项的数据对象,包含歌曲的详细信息 + */ + @Override + protected void convert(@NonNull BaseViewHolder helper, SongPlaylist.SongPlaylistBean item) { + // 设置歌曲名称 + helper.setText(R.id.tv_song_name,item.getSong_name()); + // 设置演唱者信息,添加"演唱者:"前缀 + helper.setText(R.id.tv_song_singer,"演唱者:"+item.getSinger_nickname()); + // 设置礼物信息,包含礼物名称和数量 + helper.setText(R.id.tv_gift_name,item.getGift_name()+"*"+item.getGift_num()); + // 设置礼物价格 + helper.setText(R.id.tv_gift_price,item.getGift_price()); + // 设置老板昵称,添加"老板:"前缀 + helper.setText(R.id.tv_boss_name,"老板:"+item.getBoss_nickname()); + // 加载礼物图片 + ImageUtils.loadHead(item.getBase_image(),helper.getView(R.id.iv_gift_image)); + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/WheatPositionAdapter.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/WheatPositionAdapter.java new file mode 100644 index 00000000..b739296e --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/adapter/WheatPositionAdapter.java @@ -0,0 +1,147 @@ +package com.xscm.modulemain.activity.room.adapter; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.xscm.modulemain.R; +import com.xscm.moduleutil.bean.room.RoomPitBean; + +import java.util.ArrayList; +import java.util.List; + +/** + * 麦位选择适配器 + */ +public class WheatPositionAdapter extends RecyclerView.Adapter { + + private List wheatPositions = new ArrayList<>(); + private int selectedPosition = 0; + private OnItemSelectedListener onItemSelectedListener; + + public WheatPositionAdapter(List wheatPositions) { + // 确保wheatPositions不为null + if (wheatPositions == null) { + this.wheatPositions = new ArrayList<>(); + } else { + this.wheatPositions = new ArrayList<>(wheatPositions); + } + // 添加"全部"选项 + addAllOption(); + } + + public void setWheatPositions(List wheatPositions) { + // 确保wheatPositions不为null + if (wheatPositions == null) { + this.wheatPositions = new ArrayList<>(); + } else { + this.wheatPositions = new ArrayList<>(wheatPositions); + } + // 添加"全部"选项 + addAllOption(); + notifyDataSetChanged(); + } + + /** + * 添加"全部"选项 + */ + private void addAllOption() { + // 创建一个"全部"选项的RoomPitBean + RoomPitBean allOption = new RoomPitBean(); + allOption.setId("-1"); // 使用-1作为"全部"的ID + allOption.setPit_number("全部"); + allOption.setOccupied(false); + if (wheatPositions != null) { + // 检查是否已经存在"全部"选项 + boolean hasAllOption = false; + for (RoomPitBean bean : wheatPositions) { + if ("-1".equals(bean.getId())) { + hasAllOption = true; + break; + } + } + // 如果不存在"全部"选项,则添加到列表开头 + if (!hasAllOption) { + wheatPositions.add(0, allOption); + } + } + } + + public void setSelectedPosition(int position) { + if (position >= 0 && position < wheatPositions.size()) { + int lastSelectedPosition = selectedPosition; + selectedPosition = position; + notifyItemChanged(lastSelectedPosition); + notifyItemChanged(selectedPosition); + } + } + + public void setOnItemSelectedListener(OnItemSelectedListener listener) { + this.onItemSelectedListener = listener; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_wheat_position, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + RoomPitBean wheatPosition = wheatPositions.get(position); + + // 特殊处理"全部"选项的显示 + if ("-1".equals(wheatPosition.getId())) { + holder.tvName.setText("全部"); + } else { + holder.tvName.setText(wheatPosition.getPit_number() + "号麦"); + } + + // 设置选中状态 + if (position == selectedPosition) { + holder.itemView.setBackgroundResource(com.xscm.moduleutil.R.drawable.bg_r16_3abc6d); + } else { + // "全部"选项使用默认背景,不受占用状态影响 + if ("-1".equals(wheatPosition.getId())) { + holder.itemView.setBackgroundResource(com.xscm.moduleutil.R.drawable.bg_r16_2b2935); + } else { + holder.itemView.setBackgroundResource(wheatPosition.isOccupied() ? + com.xscm.moduleutil.R.drawable.bg_r16_3abc6d : com.xscm.moduleutil.R.drawable.bg_r16_2b2935); + } + } + + // 设置点击事件 + holder.itemView.setOnClickListener(v -> { + // "全部"选项始终可点击 + if ("-1".equals(wheatPosition.getId()) || !wheatPosition.isOccupied()) { + setSelectedPosition(position); + if (onItemSelectedListener != null) { + onItemSelectedListener.onItemSelected(wheatPosition); + } + } + }); + } + + @Override + public int getItemCount() { + return wheatPositions.size(); + } + + static class ViewHolder extends RecyclerView.ViewHolder { + TextView tvName; + + public ViewHolder(@NonNull View itemView) { + super(itemView); + tvName = itemView.findViewById(R.id.tv_name); + } + } + + public interface OnItemSelectedListener { + void onItemSelected(RoomPitBean wheatPosition); + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/contacts/JukeboxContacts.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/contacts/JukeboxContacts.java new file mode 100644 index 00000000..5842d4f8 --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/contacts/JukeboxContacts.java @@ -0,0 +1,28 @@ +package com.xscm.modulemain.activity.room.contacts; + +import android.app.Activity; +import com.xscm.moduleutil.activity.IPresenter; +import com.xscm.moduleutil.activity.IView; + +/** + * com.example.moduleroom.contacts + * qx + * 2025/11/12 + */ +public class JukeboxContacts { + public interface View extends IView { + void applyPit(); + void setMutePit(String pitNumber, String is_mute); + + void setLockPit(String pitNumber, String is_lock); + } + public interface IRoomPre extends IPresenter { + void applyPit(String roomId, String pitNumber); + + void setMutePit(String roomId, String pitNumber,String is_mute);//禁麦 + + void setLockPit(String roomId, String pitNumber, String is_lock); + void singerSongCut(String id); + } + +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/contacts/RequestSongContacts.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/contacts/RequestSongContacts.java new file mode 100644 index 00000000..521c9c7b --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/contacts/RequestSongContacts.java @@ -0,0 +1,39 @@ +package com.xscm.modulemain.activity.room.contacts; + +import android.app.Activity; + +import com.xscm.moduleutil.activity.IPresenter; +import com.xscm.moduleutil.activity.IView; +import com.xscm.moduleutil.bean.SingerSongCount; +import com.xscm.moduleutil.bean.SongPlaylist; + +import java.util.List; + +public class RequestSongContacts { + + public interface View extends IView { + void getSong(SongPlaylist s); + void finishComment(); + + void singerSong(); + + //添加处理歌曲列表的方法 + void singerSongList(SongPlaylist s); + void singerSongTop(String s); + + void singerSongCount(SingerSongCount s); + } + + public interface IRoomPre extends IPresenter { + void getSong(String userId,String roomId,String page,String pageSize); + + void singerSong(String song_id,String roomId); + + void singerSongList(String room_id,String type,String page,String page_limit); + + void singerSongTop(String id); + + void singerSongCount(String roomId); + } + +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/ChatRoomFragment.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/ChatRoomFragment.java index 71951386..3b7c00cf 100644 --- a/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/ChatRoomFragment.java +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/ChatRoomFragment.java @@ -71,8 +71,10 @@ public class ChatRoomFragment extends BaseMvpFragment 0) { @@ -299,7 +300,6 @@ public class ChatRoomFragment extends BaseMvpFragment implements RequestSongContacts.View{ + + private RequestSongPagerAdapter pagerAdapter; + private final String[] tabTitles = new String[]{"点歌", "已点歌曲", "历史记录"}; + private int requestedSongsCount = 0; // 已点歌曲数量 + private int historySongsCount = 0; // 历史记录数量 + private String roomId; + + public RequestSongFragment() { + // Required empty public constructor + } + + /** + * + * @return + */ + // TODO: Rename and change types and number of parameters + public static RequestSongFragment show(FragmentManager fragmentManager) { + RequestSongFragment fragment = new RequestSongFragment(); + Bundle args = new Bundle(); + fragment.show(fragmentManager, "RequestSongFragment"); + return fragment; + } + + @Override + protected void initData() { + if (getActivity() != null) { + // 假设Activity有获取麦位数据的方法 + roomId = ((RoomActivity) getActivity()).getRoomIds(); + } + // 初始化数据 + MvpPre.singerSongCount(roomId); + } + + @Override + protected void initView() { + // 初始化ViewPager2和TabLayout + initViewPager(); + } + + private void initViewPager() { + // 创建适配器 + pagerAdapter = new RequestSongPagerAdapter(getActivity()); + + // 设置适配器 + mBinding.viewPager.setAdapter(pagerAdapter); + + // 设置TabLayout和ViewPager2的联动 + new TabLayoutMediator(mBinding.tabLayout, mBinding.viewPager, (tab, position) -> { + String title = tabTitles[position]; + if (position == 1) { // 已点歌曲 + title = "已点歌曲(" + requestedSongsCount + ")"; + } else if (position == 2) { // 历史记录 + title = "历史记录"; + } + tab.setText(title); + }).attach(); + } + + @Override + protected void initDialogStyle(Window window) { + super.initDialogStyle(window); + window.setGravity(Gravity.BOTTOM); + } + + @Override + public void onStart() { + super.onStart(); + // 注册EventBus + + Window window = getDialog().getWindow(); + if (window != null) { + // 获取屏幕高度 + WindowManager wm = getActivity().getWindowManager(); + int screenHeight = wm.getDefaultDisplay().getHeight(); + // 设置高度为屏幕高度的510/812 + int dialogHeight = (int) (screenHeight * 510.0 / 812.0); + window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, dialogHeight); + // 可选:设置动画样式(从底部弹出) + window.setWindowAnimations(com.xscm.moduleutil.R.style.CommonShowDialogBottom); + } + } + + @Override + protected int getLayoutId() { + return R.layout.fragment_request_song; + } + + @Override + protected RequestSongPresenter bindPresenter() { + return new RequestSongPresenter(this, getActivity()); + } + + @Override + public void getSong(SongPlaylist s) { + // 更新已点歌曲数量 + + } + + public void setRequestedSongsCount(int count) { + this.requestedSongsCount = count; + updateTabTitles(); + + } + + @Override + public void finishComment() { + + } + + @Override + public void singerSong() { + + } + + @Override + public void singerSongList(SongPlaylist s) { + + } + + @Override + public void singerSongTop(String s) { + + } + + @Override + public void singerSongCount(SingerSongCount s) { + requestedSongsCount=s.getAlready(); + updateTabTitles(); + } + + + /** + * 更新Tab标题显示数量 + */ + private void updateTabTitles() { + if (mBinding.tabLayout.getTabCount() > 0) { + // 更新已点歌曲Tab + if (mBinding.tabLayout.getTabAt(1) != null) { + mBinding.tabLayout.getTabAt(1).setText("已点歌曲(" + requestedSongsCount + ")"); + } + // 更新历史记录Tab + if (mBinding.tabLayout.getTabAt(2) != null) { + mBinding.tabLayout.getTabAt(2).setText("历史记录"); + } + } + } + + /** + * 设置历史记录数量 + * @param count 历史记录数量 + */ + public void setHistorySongsCount(int count) { + this.historySongsCount = count; + updateTabTitles(); + } + + /** + * 更新当前页面的数据 + */ + public void updateCurrentPageData() { + // 获取当前ViewPager选中的页面位置 + int currentItem = mBinding.viewPager.getCurrentItem(); + + // 如果是已点歌曲页面(位置1),则刷新数据 + if (currentItem == 1) { + // 获取适配器 + if (pagerAdapter != null) { + // 获取Fragment并刷新数据 + // 注意:ViewPager2中的Fragment可能还未创建或已被销毁,所以需要检查 + try { + // 通过反射获取当前显示的Fragment + androidx.viewpager2.adapter.FragmentStateAdapter adapter = pagerAdapter; + java.lang.reflect.Method createFragmentMethod = androidx.viewpager2.adapter.FragmentStateAdapter.class.getDeclaredMethod("createFragment", int.class); + createFragmentMethod.setAccessible(true); + androidx.fragment.app.Fragment fragment = (androidx.fragment.app.Fragment) createFragmentMethod.invoke(adapter, currentItem); + + // 如果是RequestedSongsFragment,则刷新数据 + if (fragment instanceof RequestedSongsFragment) { + ((RequestedSongsFragment) fragment).refreshData(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + +} \ No newline at end of file diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/RequestedSongsFragment.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/RequestedSongsFragment.java new file mode 100644 index 00000000..042c1485 --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/RequestedSongsFragment.java @@ -0,0 +1,210 @@ +package com.xscm.modulemain.activity.room.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.constant.RefreshState; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; +import com.xscm.modulemain.R; +import com.xscm.modulemain.activity.room.activity.RoomActivity; +import com.xscm.modulemain.activity.room.adapter.RequestedSongsAdapter; +import com.xscm.modulemain.activity.room.contacts.RequestSongContacts; +import com.xscm.modulemain.activity.room.presenter.RequestSongPresenter; +import com.xscm.modulemain.databinding.FragmentRequestedSongsBinding; +import com.xscm.moduleutil.base.BaseMvpFragment; +import com.xscm.moduleutil.bean.SingerSongCount; +import com.xscm.moduleutil.bean.SongPlaylist; + +import java.util.ArrayList; +import java.util.List; + +/** + * 已点歌曲页面Fragment + */ +public class RequestedSongsFragment extends BaseMvpFragment implements RequestSongContacts.View { + + private String roomId; + private int page = 1; + private RequestedSongsAdapter adapter; + private List songList = new ArrayList<>(); + + @Override + protected RequestSongPresenter bindPresenter() { + return new RequestSongPresenter(this, getActivity()); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return super.onCreateView(inflater, container, savedInstanceState); + } + + @Override + protected void initView() { + // 初始化RecyclerView + initRecyclerView(); + } + + @Override + protected void initData() { + if (getActivity() != null) { + // 假设Activity有获取麦位数据的方法 + roomId = ((RoomActivity) getActivity()).getRoomIds(); + } + + // 显示加载中状态 + mBinding.smartRefreshLayout.autoRefresh(); + } + + private void initRecyclerView() { + // 初始化RecyclerView + adapter = new RequestedSongsAdapter(); + mBinding.rvMyRequestedSongs.setLayoutManager(new LinearLayoutManager(getContext())); + mBinding.rvMyRequestedSongs.setAdapter(adapter); + + // 设置点击监听 + adapter.setOnItemClickListener(new RequestedSongsAdapter.OnItemClickListener() { + @Override + public void onPlayClick(SongPlaylist.SongPlaylistBean song, int position) { + // 处理播放点击 + if (song != null) { +// MvpPre.singerSong(song.singer_song_id, roomId); + } + } + + @Override + public void onTopClick(SongPlaylist.SongPlaylistBean song, int position) { + // 处理置顶点击 + if (song != null) { + // 这里可以添加置顶逻辑 +// ToastUtil.showShort("已置顶: " + song.song_name); + MvpPre.singerSongTop(song.getId()+""); + } + } + }); + + // 设置刷新和加载更多监听 + mBinding.smartRefreshLayout.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + page++; + MvpPre.singerSongList(roomId, "1", page + "", "10"); + } + + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + page = 1; + MvpPre.singerSongList(roomId, "1", page + "", "10"); + } + }); + } + + @Override + protected int getLayoutId() { + return R.layout.fragment_requested_songs; + } + + @Override + public void getSong(SongPlaylist s) { + // 这个方法似乎不是我们需要的,可能用于其他功能 + } + + @Override + public void finishComment() { + // 评论完成回调 + } + + @Override + public void singerSong() { + // 歌曲播放回调 + // 可以在这里更新UI,显示当前播放状态 + } + + @Override + public void singerSongList(SongPlaylist s) { + // 这个方法似乎是处理单个歌曲的,我们可能需要另一个方法处理列表 + + if (s != null &&s.getLists()!=null && s.getLists().size() > 0 ) { + // 判断当前是刷新还是加载更多 + RefreshState state = mBinding.smartRefreshLayout.getState(); + if (state == RefreshState.Refreshing) { + // 刷新,清空列表并添加新数据 + songList.clear(); + songList.addAll(s.getLists()); + adapter.setSongList(songList); + mBinding.smartRefreshLayout.finishRefresh(true); + } else if (state == RefreshState.Loading) { + // 加载更多,添加数据到列表 + if (s.getLists().size() > 0) { + songList.addAll(s.getLists()); + adapter.addSongList(songList); + adapter.setShowFooter(true); + mBinding.smartRefreshLayout.finishLoadMore(true); + } else { + // 没有更多数据 + adapter.setShowFooter(false); + mBinding.smartRefreshLayout.finishLoadMoreWithNoMoreData(); + } + } else { + // 首次加载 + songList.clear(); + songList.addAll(s.getLists()); + adapter.setSongList(songList); + mBinding.smartRefreshLayout.finishRefresh(); + } + + // 显示或隐藏空视图 + if (songList.isEmpty()) { + mBinding.tvNoRequestedSongs.setVisibility(View.VISIBLE); + mBinding.rvMyRequestedSongs.setVisibility(View.GONE); + } else { + mBinding.tvNoRequestedSongs.setVisibility(View.GONE); + mBinding.rvMyRequestedSongs.setVisibility(View.VISIBLE); + } + } else { + // 数据为空 + if (mBinding.smartRefreshLayout.getState() == RefreshState.Refreshing) { + mBinding.smartRefreshLayout.finishRefresh(false); + } else if (mBinding.smartRefreshLayout.getState() == RefreshState.Loading) { + mBinding.smartRefreshLayout.finishLoadMore(false); + } + + // 显示空视图 + mBinding.tvNoRequestedSongs.setVisibility(View.VISIBLE); + mBinding.rvMyRequestedSongs.setVisibility(View.GONE); + } + } + + @Override + public void singerSongTop(String s) { + page = 1; + MvpPre.singerSongList(roomId, "1", page + "", "10"); + } + + @Override + public void singerSongCount(SingerSongCount s) { + + } + + /** + * 刷新数据 + */ + public void refreshData() { + // 重新加载数据 + if (getActivity() != null) { + roomId = ((RoomActivity) getActivity()).getRoomIds(); + } + if (roomId != null && !roomId.isEmpty()) { + page = 1; + MvpPre.singerSongList(roomId, "1", page + "", "10"); + } + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/RoomFragment.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/RoomFragment.java index a44c5c78..3dfd2a81 100644 --- a/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/RoomFragment.java +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/RoomFragment.java @@ -98,6 +98,8 @@ public class RoomFragment extends BaseMvpFragment implements JukeboxContacts.View { + RoomInfoResp roomInfoResp; + RoomJukeboxAdapter adapter; + private String roomId; + private PopupWindow popupWindow; + protected String pitNumber;//当前点击的麦序 + private RoomPitBean roomPitBean; + private static final long CLICK_INTERVAL = 500; // 500ms内不允许重复点击 + private RequestSongFragment requestSongFragment; // 保存RequestSongFragment的引用 + private long lastClickTime = 0; + private String lastClickedUserId = ""; // 记录上次点击的用户ID + private String lastClickedPitNumber = ""; // 记录上次点击的麦位号 + private int myPitNumber; + private RoomFragment parentFragment; + private int songId;//歌曲id,当前歌曲的 + + public RoomJukeboxFragment() { + // Required empty public constructor + } + + public RoomJukeboxFragment(RoomInfoResp roomInfoResp) { + this.roomInfoResp = roomInfoResp; + } + + // TODO: Rename and change types and number of parameters + public static RoomJukeboxFragment newInstance(RoomInfoResp roomInfoResp) { + RoomJukeboxFragment fragment = new RoomJukeboxFragment(roomInfoResp); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + protected JukeboxPresenter bindPresenter() { + return new JukeboxPresenter(this, getActivity()); + } + + + @Override + protected void initData() { + setRoomInfo(roomInfoResp); + parentFragment = (RoomFragment) getParentFragment(); + } + + private void setRoomInfo(RoomInfoResp roomInfoResp) { + this.roomInfoResp = roomInfoResp; + roomId = roomInfoResp.getRoom_info().getRoom_id(); + + setView(); + } + + @Override + protected void initView() { + mBinding.guestContainer.setVisibility(GONE); + adapter = new RoomJukeboxAdapter(R.layout.item_jukebox); + GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 4); + mBinding.rvJukebox.setLayoutManager(layoutManager); + mBinding.rvJukebox.setAdapter(adapter); + adapter.setOnWheatClickListener(new RoomJukeboxAdapter.OnWheatClickListener() { + + @Override + public void onWheatClick(RoomJukeboxWheatView roomJukeboxWheatView, int position) { + + if (ClickUtils.isFastDoubleClick(roomJukeboxWheatView)) { + return; + } + + RoomPitBean pitBean = roomJukeboxWheatView.pitBean; + // 可选:点击事件处理 + Log.d("Wheat", "Clicked pit: " + position); + if (!pitBean.getUser_id().equals("0") && !pitBean.getUser_id().isEmpty()) { + RoomUserInfoFragment.show(roomId, pitBean.getUser_id(), pitBean.getPit_number(), getHostUser(), false, 3, isNumberWhether(), getChildFragmentManager()); + } else { + if (cheackWether(pitBean.getPit_number())) { + pitNumber = pitBean.getPit_number(); + roomPitBean = pitBean; + showPopupMenu(roomJukeboxWheatView); // v 是点击的按钮视图 + } else if ((position + 1) == 10) { + if (ActivityUtils.getTopActivity() instanceof RoomActivity) { + if (((RoomActivity) ActivityUtils.getTopActivity()).getHostUser() < 4) { + if (!isFastDoubleClick("online_dialog", position + 1 + "")) { + RoomOnlineDialogFragment.show(roomId, position + 1 + "", roomInfoResp.getUser_info(), roomInfoResp, getChildFragmentManager()); + } + } else { + com.hjq.toast.ToastUtils.show("请等待主持抱麦"); + } + } + + + } else { + MvpPre.applyPit(roomId, position + 1 + ""); + } + } + } + + }); + + mBinding.wvZc.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (ClickUtils.isFastDoubleClick(v)) { + return; + } + if (!mBinding.wvZc.getUserId().equals("") && !mBinding.wvZc.getUserId().equals("0")) { + RoomUserInfoFragment.show(roomInfoResp.getRoom_info().getRoom_id(), mBinding.wvZc.getUserId(), mBinding.wvZc.pitNumber, getHostUser(), false, 2, isNumberWhether(), getChildFragmentManager()); + } else { + MvpPre.applyPit(roomInfoResp.getRoom_info().getRoom_id(), "9"); + } + } + }); + + mBinding.imDg.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (ClickUtils.isFastDoubleClick(v)) { + return; + } + // 保存RequestSongFragment的引用,以便后续调用其方法 + requestSongFragment = RequestSongFragment.show(getChildFragmentManager()); + } + }); + + mBinding.imQg.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + MvpPre.singerSongCut(songId+""); + } + }); + } + + + /** + * 检查是否为快速重复点击 + * + * @param userId 用户ID + * @param pitNumber 麦位号 + * @return true表示是快速重复点击,false表示不是 + */ + private boolean isFastDoubleClick(String userId, String pitNumber) { + long currentTime = System.currentTimeMillis(); + if (currentTime - lastClickTime < CLICK_INTERVAL && + userId.equals(lastClickedUserId) && + pitNumber.equals(lastClickedPitNumber)) { + return true; // 是快速重复点击 + } + + // 更新上次点击信息 + lastClickTime = currentTime; + lastClickedUserId = userId; + lastClickedPitNumber = pitNumber; + return false; // 不是快速重复点击 + } + + private void showPopupMenu(View anchorView) { + if (popupWindow != null && !popupWindow.isShowing()) { + // 获取锚点视图的坐标 + int[] location = new int[2]; + anchorView.getLocationOnScreen(location); + + // 设置弹出位置 + popupWindow.showAtLocation(anchorView, Gravity.NO_GRAVITY, location[0], location[1] + anchorView.getHeight()); + + setPopupMenuClickListener(popupWindow.getContentView(), anchorView); + } + } + + private void setPopupMenuClickListener(View popupView, View view) { + + TextView tvHugMic = popupView.findViewById(R.id.tv_hug_mic); + Switch switchCloseMic = popupView.findViewById(R.id.sw_close_mic); + Switch switchLockMic = popupView.findViewById(R.id.sw_lock_mic); + if (view != null) { + switchCloseMic.setChecked(roomPitBean.getIs_mute() == 1 ? true : false);//是否禁麦 + switchLockMic.setChecked(roomPitBean.getIs_lock() == 1 ? true : false);//是否闭麦 + } + switchCloseMic.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + MvpPre.setMutePit(roomId, pitNumber + "", b ? "2" : "4"); + } + }); + + + switchLockMic.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + MvpPre.setLockPit(roomId, pitNumber + "", b ? "1" : "0"); + } + }); + + + tvHugMic.setOnClickListener(v -> { + // 处理抱麦逻辑 + RoomOnlineDialogFragment.show(roomId, pitNumber, roomInfoResp.getUser_info(), roomInfoResp, getChildFragmentManager()); + popupWindow.dismiss(); + }); + } + + private int isNumberWhether() { + if (roomInfoResp.getUser_info().getPit_number() == 9) { + return 1; + } + return 0; + } + + private int getHostUser() { + if (roomInfoResp.getUser_info().getPit_number() == 9) { + if (roomInfoResp.getUser_info().getIs_room_owner() == 1) { + return 1; + } else if (roomInfoResp.getUser_info().getIs_management() == 1) { + return 2; + } else if (roomInfoResp.getUser_info().getIs_host() == 1) { + return 3; + } else { + return 4; + } + } else { + if (roomInfoResp.getUser_info().getIs_room_owner() == 1) { + return 1; + } + if (roomInfoResp.getUser_info().getIs_management() == 1) { + return 2; + } + if (roomInfoResp.getUser_info().getIs_host() == 1) { + return 3; + } + return 4; + } + } + + private boolean cheackWether(String pitNumber) { + if (roomInfoResp.getRoom_info().getRoom_up_pit_type().equals("1")) {//排麦模式 + if (roomInfoResp.getUser_info().getIs_management() == 1 + || roomInfoResp.getUser_info().getIs_host() == 1 + || roomInfoResp.getUser_info().getIs_room_owner() == 1) { + if (pitNumber.equals("9")) { + return false; + } + return true; + } + return false; + } else { + if (roomInfoResp.getRoom_info().getPit_list().size() > 8) { + if (roomInfoResp.getUser_info().getPit_number() == 9 && !pitNumber.equals("10")) { + return true; + } + return false; + } + return false; + } + } + + @Override + protected int getLayoutId() { + return R.layout.fragment_jukebox; + } + + + public void roomInfoUpdate(RoomInfoResp roomInfoResp) { + this.roomInfoResp = roomInfoResp; + roomId = roomInfoResp == null ? "" : roomInfoResp.getRoom_info().getRoom_id(); + + setView(); + } + + public void setView() { + List roomPitBeans = new ArrayList<>(); + for (int i = 0; i < roomInfoResp.getRoom_info().getPit_list().size(); i++) { + RoomPitBean roomPitBean = roomInfoResp.getRoom_info().getPit_list().get(i); + + if (!roomPitBean.getPit_number().equals("9") && !roomPitBean.getPit_number().equals("10")) { + roomPitBeans.add(roomPitBean); + } else if (roomPitBean.getPit_number().equals("9")) { + // 确保视图的pitNumber与数据的pit_number匹配 + mBinding.wvZc.setRoomWheatNumber("9"); + mBinding.wvZc.setData(roomPitBean); + } + } + adapter.setNewData(roomPitBeans); + + if (roomInfoResp.getSinger_info()!=null){ + if (roomInfoResp.getSinger_info().getSong_info()!=null){ + mBinding.tvPerformerName.setVisibility(GONE); + mBinding.tvNetName.setVisibility(VISIBLE); + mBinding.ciNetAva.setVisibility(VISIBLE); + ImageUtils.loadHead(roomInfoResp.getSinger_info().getSong_info().getSinger_avatar(),mBinding.ciUserAva); + mBinding.tvSong.setText("演唱歌曲:"+roomInfoResp.getSinger_info().getSong_info().getSong_name()); + ImageUtils.loadHead(roomInfoResp.getSinger_info().getSong_info().getBoss_avatar(),mBinding.ciNetAva); + mBinding.tvNetName.setText("老板"); + songId= roomInfoResp.getSinger_info().getSong_info().getSinger_song_id(); + + if (roomInfoResp.getSinger_info().getNext_song_info()!=null){ + mBinding.guestContainer.setVisibility(View.VISIBLE); + ImageUtils.loadHead(roomInfoResp.getSinger_info().getNext_song_info().getSinger_avatar(),mBinding.ciGsAva); + mBinding.tvGsName.setText(roomInfoResp.getSinger_info().getNext_song_info().getSinger_nickname()); + }else { + mBinding.guestContainer.setVisibility(GONE); + } + + String userId= String.valueOf(roomInfoResp.getSinger_info().getSong_info().getSinger_user_id()); + if(mBinding.wvZc.getUserId().equals(userId)){ + mBinding.wvZc.pitBean.setImageType(true); + mBinding.wvZc.setData(mBinding.wvZc.pitBean); + }else { + for (RoomPitBean roomPitBean : roomPitBeans) { + if (roomPitBean.getUser_id().equals(userId)){ + roomPitBean.setImageType(true); + }else { + roomPitBean.setImageType(false); + } + } + adapter.notifyDataSetChanged(); + } + }else { + mBinding.tvNetName.setVisibility(GONE); + mBinding.ciNetAva.setVisibility(GONE); + } + + } + } + + @Override + public void applyPit() { + + } + + @Override + public void setMutePit(String pitNumber, String is_mute) { + + } + + @Override + public void setLockPit(String pitNumber, String is_lock) { + + } + + public void event1003(RoomMessageEvent messageEvent) { + UserInfo fromUserInfo = messageEvent.getText().getFromUserInfo(); + if (fromUserInfo == null) return; + + String pitNumber = messageEvent.getText().getPit_number(); + int userId = fromUserInfo.getUser_id(); + + // 获取适配器数据 + List dataList = adapter.getData(); + int position = Integer.parseInt(pitNumber) - 1; + // 确保位置有效 + if (position < 0 || (position >= dataList.size() && !pitNumber.equals("9"))) { + return; + } + + if (pitNumber.equals("9") || pitNumber.equals("10")) { + RoomPitBean pitBean = new RoomPitBean(); + pitBean.setPit_number(pitNumber); + pitBean.setUser_id(userId + ""); + pitBean.setAvatar(fromUserInfo.getAvatar()); + pitBean.setNickname(fromUserInfo.getNickname()); + pitBean.setSex(fromUserInfo.getSex() + ""); + pitBean.setCharm(fromUserInfo.getCharm()); + pitBean.setDress(fromUserInfo.getDress()); + + // 确保视图的pitNumber与数据的pit_number匹配 + if (pitNumber.equals("9")) { + mBinding.wvZc.setRoomWheatNumber("9"); + mBinding.wvZc.setData(pitBean); + } + + } else { + // 获取对应位置的bean并更新 + RoomPitBean pitBean = dataList.get(position); + pitBean.setUser_id(userId + ""); + pitBean.setAvatar(fromUserInfo.getAvatar()); + pitBean.setNickname(fromUserInfo.getNickname()); + pitBean.setSex(fromUserInfo.getSex() + ""); + pitBean.setCharm(fromUserInfo.getCharm()); + pitBean.setDress(fromUserInfo.getDress()); + + // 使用set方法更新数据,然后通知适配器 + dataList.set(position, pitBean); + adapter.notifyItemChanged(position); + } + + + if (userId == SpUtil.getUserId()) { + myPitNumber = Integer.parseInt(pitNumber); + if (pitNumber.equals("9")) { + configGameOptionBtn(); + } + } + } + + /// 配置操作按钮 + private void configGameOptionBtn() { + if (myPitNumber == 9) { + mBinding.imQg.setVisibility(VISIBLE); + } else { + mBinding.imQg.setVisibility(GONE); + } + } + + public void event1004(RoomMessageEvent messageEvent) { + boolean b = false; + String pitNumber = messageEvent.getText().getPit_number(); + int userId = messageEvent.getText().getFromUserInfo().getUser_id(); + if (pitNumber.equals("9") || pitNumber.equals("10")) { + RoomPitBean pitBean = new RoomPitBean(); + pitBean.setPit_number(pitNumber); + pitBean.setUser_id(""); + pitBean.setAvatar(""); + pitBean.setNickname(""); + pitBean.setSex(""); + pitBean.setCharm(""); + + if (pitNumber.equals("9")) { + RoomJukeboxWheatView roomDefaultWheatView = mBinding.wvZc; + roomDefaultWheatView.setRoomWheatNumber("9"); + roomDefaultWheatView.setData(pitBean); + } + + if (SpUtil.getUserId() == messageEvent.getText().getFromUserInfo().getUser_id()) { + b = true; + AgoraManager.getInstance().ClientRole(false); + AgoraManager.getInstance().muteLocalAudioStream(true); + } else { + b = false; + } + + if (parentFragment != null) { + parentFragment.updateWheatStatus(pitBean, Integer.parseInt(pitNumber), false, b); + } + } else { + // 获取适配器数据 + List dataList = adapter.getData(); + int position = Integer.parseInt(pitNumber) - 1; + + // 确保位置有效 + if (position < 0 || position >= dataList.size()) { + return; + } + + // 获取对应位置的bean并更新 + RoomPitBean pitBean = dataList.get(position); + pitBean.setUser_id(""); + pitBean.setAvatar(""); + pitBean.setNickname(""); + pitBean.setSex(""); + pitBean.setCharm(""); + pitBean.setDress(""); + + // 使用set方法更新数据,然后通知适配器 + dataList.set(position, pitBean); + adapter.notifyItemChanged(position); + } + if (userId == SpUtil.getUserId()) { + myPitNumber = 0; + if (pitNumber.equals("9")) { + configGameOptionBtn(); + } + } + } + + public void event1039(RoomMessageEvent event) { + String fromPit = event.getText().getFrom_pit_number(); + String toPit = event.getText().getTo_pit_number(); + if (fromPit == null || toPit == null) return; + List dataList = new ArrayList<>(adapter.getData()); + int fromIndex = Integer.parseInt(fromPit) - 1; + int toIndex = Integer.parseInt(toPit) - 1; + if(toIndex>adapter.getData().size()-1){ + UserInfo fromUserInfo=event.getText().getFromUserInfo(); + pitNumber= toPit; + RoomPitBean pitBean = new RoomPitBean(); + pitBean.setPit_number(pitNumber); + pitBean.setUser_id(fromUserInfo.getUser_id() + ""); + pitBean.setAvatar(fromUserInfo.getAvatar()); + pitBean.setNickname(fromUserInfo.getNickname()); + pitBean.setSex(fromUserInfo.getSex() + ""); + pitBean.setCharm(fromUserInfo.getCharm()); + pitBean.setDress(fromUserInfo.getDress()); + + // 确保视图的pitNumber与数据的pit_number匹配 + if (pitNumber.equals("9")) { + mBinding.wvZc.setRoomWheatNumber("9"); + mBinding.wvZc.setData(pitBean); + } + RoomPitBean temp = dataList.get(fromIndex); + temp.setUser_id(""); + temp.setAvatar(""); + temp.setNickname(""); + temp.setSex(""); + temp.setCharm(""); + temp.setDress(""); + dataList.set(fromIndex,temp); + adapter.notifyDataSetChanged(); + return; + } + + // 获取当前数据列表 + + + // 保存原始pit_number + String fromPitNumber = dataList.get(fromIndex).getPit_number(); + String toPitNumber = dataList.get(toIndex).getPit_number(); + + // 交换两个位置的对象 + RoomPitBean temp = dataList.get(fromIndex); + dataList.set(fromIndex, dataList.get(toIndex)); + dataList.set(toIndex, temp); + + // 确保pit_number正确 + dataList.get(fromIndex).setPit_number(fromPitNumber); + dataList.get(toIndex).setPit_number(toPitNumber); + + // 更新数据并通知适配器 + adapter.getData().clear(); + adapter.getData().addAll(dataList); + adapter.notifyDataSetChanged(); + } + + /** + * 更新已点歌曲数量 + * + * @param messageEvent 已点歌曲数量 + */ + public void event1072(RoomMessageEvent messageEvent) { + int count = messageEvent.getText().getCount(); + + if (requestSongFragment != null && requestSongFragment.isVisible()) { + requestSongFragment.setRequestedSongsCount(count); + requestSongFragment.updateCurrentPageData(); + } + } + + // TODO: 2025/11/18 下一首歌的演唱者 + public void event1071(RoomMessageEvent messageEvent) { + if (messageEvent.getText().getNext_song_info()!=null){ + mBinding.guestContainer.setVisibility(View.VISIBLE); + ImageUtils.loadHead(messageEvent.getText().getNext_song_info().getSinger_avatar(),mBinding.ciGsAva); + mBinding.tvGsName.setText(messageEvent.getText().getNext_song_info().getSinger_nickname()); + } + } + + // TODO: 2025/11/18 当前 歌曲的演唱者 + public void event1070(RoomMessageEvent messageEvent) { + + if(messageEvent.getText().getSong_info()!=null){ + mBinding.tvPerformerName.setVisibility(GONE); + mBinding.tvNetName.setVisibility(VISIBLE); + mBinding.ciNetAva.setVisibility(VISIBLE); + ImageUtils.loadHead(messageEvent.getText().getSong_info().getSinger_avatar(),mBinding.ciUserAva); + mBinding.tvSong.setText("演唱歌曲:"+messageEvent.getText().getSong_info().getSong_name()); + + ImageUtils.loadHead(messageEvent.getText().getSong_info().getBoss_avatar(),mBinding.ciNetAva); + mBinding.tvNetName.setText("老板"); + songId= messageEvent.getText().getSong_info().getSinger_song_id(); + String userId= String.valueOf(messageEvent.getText().getSong_info().getSinger_user_id()); + if(mBinding.wvZc.getUserId().equals(userId)){ + mBinding.wvZc.pitBean.setImageType(true); + mBinding.wvZc.setData(mBinding.wvZc.pitBean); + }else { + for (RoomPitBean roomPitBean : adapter.getData()) { + if (roomPitBean.getUser_id().equals(userId)){ + roomPitBean.setImageType(true); + }else { + roomPitBean.setImageType(false); + } + } + adapter.notifyDataSetChanged(); + } + } + } +} \ No newline at end of file diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/SongHistoryFragment.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/SongHistoryFragment.java new file mode 100644 index 00000000..d0316fa3 --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/SongHistoryFragment.java @@ -0,0 +1,231 @@ +package com.xscm.modulemain.activity.room.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.HorizontalScrollView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.constant.RefreshState; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; +import com.xscm.modulemain.R; +import com.xscm.modulemain.activity.room.activity.RoomActivity; +import com.xscm.modulemain.activity.room.adapter.SongHistoryAdapter; +import com.xscm.modulemain.activity.room.contacts.RequestSongContacts; +import com.xscm.modulemain.activity.room.presenter.RequestSongPresenter; +import com.xscm.modulemain.databinding.FragmentSongHistoryBinding; +import com.xscm.modulemain.activity.room.fragment.RequestSongFragment; +import com.xscm.moduleutil.base.BaseFragment; +import com.xscm.moduleutil.base.BaseMvpFragment; +import com.xscm.moduleutil.bean.SingerSongCount; +import com.xscm.moduleutil.bean.SongPlaylist; + +import java.util.ArrayList; +import java.util.List; + +/** + * 历史记录页面Fragment + */ +public class SongHistoryFragment extends BaseMvpFragment implements RequestSongContacts.View { + + private String currentTimeFilter = "today"; // 默认为今日 + private int page = 1; + private String roomId; + private String type="1"; + + private SongHistoryAdapter adapter; + + @Override + protected RequestSongPresenter bindPresenter() { + return new RequestSongPresenter(this,getActivity()); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return super.onCreateView(inflater, container, savedInstanceState); + } + + @Override + protected void initView() { + if (getActivity() != null) { + // 假设Activity有获取麦位数据的方法 + roomId = ((RoomActivity) getActivity()).getRoomIds(); + } + // 初始化时间筛选 + initTimeFilters(); + + // 初始化RecyclerView + initRecyclerView(); + } + + @Override + protected void initData() { + + } + + private void initTimeFilters() { + // 设置默认选中今日 + mBinding.tvFilterToday.setBackgroundResource(com.xscm.moduleutil.R.drawable.bg_r16_3abc6d); + updateHistoryList(); + // 今日点击事件 + mBinding.tvFilterToday.setOnClickListener(v -> { + if (!currentTimeFilter.equals("today")) { + resetFilterStyles(); + mBinding.tvFilterToday.setBackgroundResource(com.xscm.moduleutil.R.drawable.bg_r16_3abc6d); + currentTimeFilter = "today"; + type="1"; + updateHistoryList(); + } + }); + + // 昨日点击事件 + mBinding.tvFilterYesterday.setOnClickListener(v -> { + if (!currentTimeFilter.equals("yesterday")) { + resetFilterStyles(); + mBinding.tvFilterYesterday.setBackgroundResource(com.xscm.moduleutil.R.drawable.bg_r16_3abc6d); + currentTimeFilter = "yesterday"; + type="2"; + updateHistoryList(); + } + }); + + // 本周点击事件 + mBinding.tvFilterThisWeek.setOnClickListener(v -> { + if (!currentTimeFilter.equals("this_week")) { + resetFilterStyles(); + mBinding.tvFilterThisWeek.setBackgroundResource(com.xscm.moduleutil.R.drawable.bg_r16_3abc6d); + currentTimeFilter = "this_week"; + type="3"; + updateHistoryList(); + } + }); + + // 上周点击事件 + mBinding.tvFilterLastWeek.setOnClickListener(v -> { + if (!currentTimeFilter.equals("last_week")) { + resetFilterStyles(); + mBinding.tvFilterLastWeek.setBackgroundResource(com.xscm.moduleutil.R.drawable.bg_r16_3abc6d); + currentTimeFilter = "last_week"; + type="4"; + updateHistoryList(); + } + }); + } + + private void resetFilterStyles() { + mBinding.tvFilterToday.setBackgroundResource(com.xscm.moduleutil.R.drawable.bg_r16_2b2935); + mBinding.tvFilterYesterday.setBackgroundResource(com.xscm.moduleutil.R.drawable.bg_r16_2b2935); + mBinding.tvFilterThisWeek.setBackgroundResource(com.xscm.moduleutil.R.drawable.bg_r16_2b2935); + mBinding.tvFilterLastWeek.setBackgroundResource(com.xscm.moduleutil.R.drawable.bg_r16_2b2935); + } + + private void initRecyclerView() { + // 初始化RecyclerView,设置适配器等 + // binding.rvSongHistory.setAdapter(adapter); + adapter=new SongHistoryAdapter(); + mBinding.rvSongHistory.setLayoutManager(new LinearLayoutManager(getActivity())); + mBinding.rvSongHistory.setAdapter(adapter); + // 设置刷新和加载更多监听 + mBinding.smartRefreshLayout.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + page++; + MvpPre.singerSongList(roomId, type, page + "", "10"); + } + + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + page = 1; + MvpPre.singerSongList(roomId, type, page + "", "10"); + } + }); + } + + private void updateHistoryList() { + // 根据选择的时间筛选条件更新历史记录列表 + // 可以在这里调用接口获取对应时间段的历史记录 + page = 1; + MvpPre.singerSongList(roomId, type, page + "", "10"); + } + + @Override + protected int getLayoutId() { + return R.layout.fragment_song_history; + } + + @Override + public void getSong(SongPlaylist s) { + + } + + @Override + public void finishComment() { + + } + + @Override + public void singerSong() { + + } + private List songList = new ArrayList<>(); + + @Override + public void singerSongList(SongPlaylist s) { + + if (s != null &&s.getLists()!=null && s.getLists().size() > 0 ) { + // 判断当前是刷新还是加载更多 + RefreshState state = mBinding.smartRefreshLayout.getState(); + if (state == RefreshState.Refreshing) { + // 刷新,清空列表并添加新数据 + songList.clear(); + songList.addAll(s.getLists()); + adapter.setNewData(songList); + mBinding.smartRefreshLayout.finishRefresh(true); + } else if (state == RefreshState.Loading) { + // 加载更多,添加数据到列表 + if (s.getLists().size() > 0) { + songList.addAll(s.getLists()); + adapter.addData(songList); + mBinding.smartRefreshLayout.finishLoadMore(true); + } else { + // 没有更多数据 + mBinding.smartRefreshLayout.finishLoadMoreWithNoMoreData(); + } + } else { + // 首次加载 + songList.clear(); + songList.addAll(s.getLists()); + adapter.setNewData(songList); + mBinding.smartRefreshLayout.finishRefresh(); + } + + } else { + // 数据为空 + if (mBinding.smartRefreshLayout.getState() == RefreshState.Refreshing) { + mBinding.smartRefreshLayout.finishRefresh(false); + } else if (mBinding.smartRefreshLayout.getState() == RefreshState.Loading) { + mBinding.smartRefreshLayout.finishLoadMore(false); + } + + } + } + + @Override + public void singerSongTop(String s) { + + } + + @Override + public void singerSongCount(SingerSongCount s) { + + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/SongRequestFragment.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/SongRequestFragment.java new file mode 100644 index 00000000..3c4ac8a4 --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/fragment/SongRequestFragment.java @@ -0,0 +1,184 @@ +package com.xscm.modulemain.activity.room.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; +import com.xscm.modulemain.R; +import com.xscm.modulemain.activity.room.activity.RoomActivity; +import com.xscm.modulemain.activity.room.contacts.RequestSongContacts; +import com.xscm.modulemain.activity.room.presenter.RequestSongPresenter; +import com.xscm.modulemain.activity.room.adapter.SongAdapter; +import com.xscm.modulemain.activity.room.adapter.WheatPositionAdapter; +import com.xscm.modulemain.databinding.FragmentSongRequestBinding; +import com.xscm.moduleutil.base.BaseMvpFragment; +import com.xscm.moduleutil.bean.SingerSongCount; +import com.xscm.moduleutil.bean.SongPlaylist; +import com.xscm.moduleutil.bean.room.RoomPitBean; + +import java.util.ArrayList; +import java.util.List; + +/** + * 点歌页面Fragment + */ +public class SongRequestFragment extends BaseMvpFragment implements RequestSongContacts.View { + + private WheatPositionAdapter wheatPositionAdapter; + private int selectedWheatPosition = 0; // 默认选中第一个麦位 + private String roomId; + private int page = 0; + + private SongAdapter adapter; + + @Override + protected RequestSongPresenter bindPresenter() { + return new RequestSongPresenter(this, getActivity()); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return super.onCreateView(inflater, container, savedInstanceState); + } + + @Override + protected void initView() { + // 初始化麦位选择 + initWheatPositions(); + // 初始化RecyclerView + initRecyclerView(); + } + + @Override + protected void initData() { + // 加载数据 + loadWheatPositions(); + } + + private void loadWheatPositions() { + // 从Activity获取麦位数据 + List wheatPositions = new ArrayList<>(); + + // 这里应该从Activity获取实际数据,这里仅为示例 + if (getActivity() != null) { + // 假设Activity有获取麦位数据的方法 + wheatPositions = ((RoomActivity) getActivity()).getRoomInfoResp(); + roomId = ((RoomActivity) getActivity()).getRoomIds(); + } + + // 更新适配器数据 + wheatPositionAdapter.setWheatPositions(wheatPositions); + + // 默认选中第一个可用麦位 + if (wheatPositions!=null&&!wheatPositions.isEmpty()) { + selectedWheatPosition = Integer.parseInt(wheatPositions.get(0).getId()); + wheatPositionAdapter.setSelectedPosition(0); + updateSongList(selectedWheatPosition); + } + + MvpPre.getSong("", roomId, "1", "20"); + } + + private void initWheatPositions() { + // 初始化麦位RecyclerView + wheatPositionAdapter = new WheatPositionAdapter(new ArrayList<>()); + wheatPositionAdapter.setOnItemSelectedListener(position -> { + selectedWheatPosition = Integer.parseInt(position.getUser_id()); + updateSongList(selectedWheatPosition); + }); + + mBinding.rvWheatPositions.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false)); + mBinding.rvWheatPositions.setAdapter(wheatPositionAdapter); + } + + private void initRecyclerView() { + // 初始化歌曲RecyclerView,设置适配器等 + // mBinding.rvRequestSongs.setAdapter(adapter); + + adapter = new SongAdapter(new ArrayList<>()); + mBinding.rvRequestSongs.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + mBinding.rvRequestSongs.setAdapter(adapter); + + mBinding.smartRefreshLayout.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + page++; + MvpPre.getSong("", roomId, page + "", "10"); + } + + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { +// EventBus.getDefault().post(new BannerRefreshEvent()); + page = 1; + MvpPre.getSong("", roomId, page + "", "10"); + } + }); + + adapter.setOnSongClickListener(new SongAdapter.OnSongClickListener() { + + @Override + public void onSongClick(SongPlaylist.SongPlaylistBean song, int position) { + MvpPre.singerSong(song.getId() + "", roomId); + } + }); + + } + + private void updateSongList(int wheatPosition) { + // 根据选中的麦位更新歌曲列表 + // 可以在这里调用接口获取对应麦位的歌曲列表 + MvpPre.getSong(wheatPosition + "", "", "1", "10"); + + } + + @Override + protected int getLayoutId() { + return R.layout.fragment_song_request; + } + + @Override + public void getSong(SongPlaylist s) { + if (s != null && s.getLists() != null && s.getLists().size() > 0) { + adapter.setSongList(s.getLists()); + mBinding.smartRefreshLayout.finishRefresh(); + mBinding.smartRefreshLayout.finishLoadMore(); + } else { + mBinding.smartRefreshLayout.finishRefresh(); + mBinding.smartRefreshLayout.finishLoadMore(); + } + } + + @Override + public void finishComment() { + + } + + @Override + public void singerSong() { + + } + + @Override + public void singerSongList(SongPlaylist s) { + + } + + @Override + public void singerSongTop(String s) { + + } + + @Override + public void singerSongCount(SingerSongCount s) { + + } + +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/presenter/JukeboxPresenter.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/presenter/JukeboxPresenter.java new file mode 100644 index 00000000..0e567e28 --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/presenter/JukeboxPresenter.java @@ -0,0 +1,96 @@ +package com.xscm.modulemain.activity.room.presenter; + +import android.content.Context; + + +import com.xscm.modulemain.activity.room.contacts.JukeboxContacts; +import com.xscm.moduleutil.http.BaseObserver; +import com.xscm.moduleutil.http.RetrofitClient; +import com.xscm.moduleutil.presenter.BasePresenter; + +import java.lang.ref.WeakReference; + +import io.reactivex.disposables.Disposable; + +/** + * com.example.moduleroom.presenter + * qx + * 2025/11/12 + */ +public class JukeboxPresenter extends BasePresenter implements JukeboxContacts.IRoomPre{ + JukeboxContacts.View mView; + public JukeboxPresenter(JukeboxContacts.View view, Context context) { + super(view, context); + mView = view; + } + + @Override + public void applyPit(String roomId, String pitNumber) { + RetrofitClient.getInstance().applyPit(roomId, pitNumber, new BaseObserver() { + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(String s) { + if (MvpRef==null){ + MvpRef=new WeakReference<>(mView); + } + MvpRef.get().applyPit(); + } + }); + } + + @Override + public void setMutePit(String roomId, String pitNumber, String is_mute) { + RetrofitClient.getInstance().setMutePit(roomId, pitNumber, is_mute, new BaseObserver() { + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(String string) { + if (MvpRef==null){ + MvpRef=new WeakReference<>(mView); + } + MvpRef.get().setMutePit(pitNumber, is_mute); + } + }); + } + + @Override + public void setLockPit(String roomId, String pitNumber, String is_lock) { + RetrofitClient.getInstance().setLockPit(roomId, pitNumber, is_lock, new BaseObserver() { + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(String string) { + if (MvpRef==null){ + MvpRef=new WeakReference<>(mView); + } + MvpRef.get().setLockPit(pitNumber, is_lock); + } + }); + } + + @Override + public void singerSongCut(String id) { + api.singerSongCut(id, new BaseObserver() { + + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(String s) { + + } + }); + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/presenter/RequestSongPresenter.java b/MainModule/src/main/java/com/xscm/modulemain/activity/room/presenter/RequestSongPresenter.java new file mode 100644 index 00000000..d09293a7 --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/presenter/RequestSongPresenter.java @@ -0,0 +1,114 @@ +package com.xscm.modulemain.activity.room.presenter; + +import android.content.Context; + +import com.xscm.modulemain.activity.room.contacts.RequestSongContacts; +import com.xscm.moduleutil.bean.SingerSongCount; +import com.xscm.moduleutil.bean.SongPlaylist; +import com.xscm.moduleutil.http.BaseObserver; +import com.xscm.moduleutil.presenter.BasePresenter; + +import java.lang.ref.WeakReference; +import java.util.List; + +import io.reactivex.disposables.Disposable; + +public class RequestSongPresenter extends BasePresenter implements RequestSongContacts.IRoomPre { + RequestSongContacts.View mView; + + public RequestSongPresenter(RequestSongContacts.View view, Context context) { + super(view, context); + mView = view; + } + + @Override + public void getSong(String userId, String roomId, String page, String pageSize) { + api.getSong(userId, roomId, page, pageSize, new BaseObserver() { + + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(SongPlaylist songPlaylist) { + if (MvpRef == null) { + MvpRef = new WeakReference<>(mView); + } + MvpRef.get().getSong(songPlaylist); + MvpRef.get().finishComment(); + } + }); + } + + @Override + public void singerSong(String song_id, String roomId) { + api.singerSong(song_id, roomId, new BaseObserver() { + + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(String s) { + if (MvpRef == null) + MvpRef = new WeakReference<>(mView); + MvpRef.get().singerSong(); + } + }); + } + + @Override + public void singerSongList(String room_id, String type, String page, String page_limit) { + api.singerSongList(room_id, type, page, page_limit, new BaseObserver() { + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(SongPlaylist songPlaylistBean) { + if (MvpRef == null) + MvpRef = new WeakReference<>(mView); + MvpRef.get().singerSongList(songPlaylistBean); + } + }); + } + + @Override + public void singerSongTop(String id) { + api.singerSongTop(id, new BaseObserver() { + + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(String s) { + if (MvpRef == null) + MvpRef = new WeakReference<>(mView); + MvpRef.get().singerSongTop(s); + } + }); + } + + @Override + public void singerSongCount(String roomId) { + api.singerSongCount(roomId, new BaseObserver() { + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(SingerSongCount singerSongCount) { + if (MvpRef == null) + MvpRef = new WeakReference<>(mView); + MvpRef.get().singerSongCount(singerSongCount); + } + }); + } + +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/user/activity/NobleDetailsActivity.java b/MainModule/src/main/java/com/xscm/modulemain/activity/user/activity/NobleDetailsActivity.java index 68946d0b..34775aff 100644 --- a/MainModule/src/main/java/com/xscm/modulemain/activity/user/activity/NobleDetailsActivity.java +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/user/activity/NobleDetailsActivity.java @@ -44,6 +44,7 @@ public class NobleDetailsActivity extends BaseMvpActivity implements SingerVerificationContract.View { + // 权限请求码 + private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200; + // 录音权限 + private static final String[] PERMISSIONS = {Manifest.permission.RECORD_AUDIO}; + + // 录音和播放相关变量 + private MediaRecorder mediaRecorder; // 媒体录音对象 + private MediaPlayer mediaPlayer; // 媒体播放对象 + private File recordingFile; // 录音文件 + private final Handler handler = new Handler(Looper.getMainLooper()); // 主线程Handler + private long recordingStartTime; // 录音开始时间 + private boolean isRecording = false; // 是否正在录音 + private boolean isPlaying = false; // 是否正在播放 + private long recordingDuration = 0L; // 录音时长 + private Timer timer; // 计时器 + + private int isSinger;//传递过来的参数, + /** + * 绑定Presenter + * @return 返回该Activity对应的Presenter实例 + */ + @Override + protected SingerVerificationPresenter bindPresenter() { + return new SingerVerificationPresenter(this, this); + } + + + /** + * 获取布局ID + * @return 返回Activity的布局资源ID + */ + @Override + protected int getLayoutId() { + return R.layout.activity_singer_verification; + } + + /** + * 初始化视图 + * 设置UI组件的初始状态和事件监听 + */ + @Override + protected void initView() { + super.initView(); + + // 请求录音权限 + if (!hasPermissions()) { + ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_RECORD_AUDIO_PERMISSION); + } + mBinding.progressArc.setProgress(0); + mBinding.progressArc.setMax(100); // 设置最大值 + mBinding.progressArc.setIndeterminate(false); + // 设置长按录音逻辑 + mBinding.recordButton.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + if (!isRecording && !isPlaying && recordingFile == null) { + startRecording(); + } + return true; + case MotionEvent.ACTION_UP: + if (isRecording) { + stopRecording(); + } + return true; + default: + return false; + } + } + }); +// 设置播放按钮点击事件 + mBinding.playButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (isPlaying) { + // 正在播放,点击停止播放 + stopPlaying(); + // 恢复按钮状态 + mBinding.playButton.setText("试听"); + mBinding.playButton.setCompoundDrawablesWithIntrinsicBounds(0, R.mipmap.but_st, 0, 0); + } else { + // 未播放,点击开始播放 + startPlaying(); + // 更改按钮状态为"结束" + mBinding.playButton.setText("结束"); + mBinding.playButton.setCompoundDrawablesWithIntrinsicBounds(0, R.mipmap.but_tz, 0, 0); + } + } + }); +// + mBinding.reRecordButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + reRecord(); + } + }); +//认证 + mBinding.imSubmit.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + submitVerification(); + } + }); + } + + @Override + protected void initData() { + mBinding.topBar.setTitle("歌手认证"); + mBinding.topBar.setColor(getResources().getColor(R.color.white)); + isSinger= getIntent().getIntExtra("isSinger",-1); + if (isSinger==-1){ + mBinding.clCorner.setVisibility(VISIBLE); + mBinding.cornerStatus.setText("暂未认证"); + }else if (isSinger==0){ + mBinding.clCorner.setVisibility(GONE); + mBinding.cornerStatus.setText("认证中"); + }else if (isSinger==1){ + mBinding.clCorner.setVisibility(GONE); + mBinding.cornerStatus.setText("已认证"); + }else if (isSinger==2){ + mBinding.clCorner.setVisibility(VISIBLE); + mBinding.cornerStatus.setText("认证失败"); + } + } + + /** + * 检查应用是否拥有所有必要的权限 + * 遍历权限列表,检查每个权限是否已被授予 + * + * @return 如果所有权限都已授予则返回true,否则返回false + */ + private boolean hasPermissions() { + // 遍历权限数组中的每个权限 + for (String permission : PERMISSIONS) { + // 检查当前权限是否已被授予 + // 如果权限未被授予(返回值不等于PERMISSION_GRANTED),则返回false + if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { + return false; + } + } + // 如果所有权限都已检查并授予,则返回true + return true; + } + + // 开始录音 + private void startRecording() { + if (!hasPermissions()) { + ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_RECORD_AUDIO_PERMISSION); + return; + } + + // 停止可能正在播放的音频 + stopPlaying(); + + // 创建录音文件 + try { + recordingFile = createAudioFile(); + + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setOutputFile(recordingFile.getAbsolutePath()); + mediaRecorder.prepare(); + mediaRecorder.start(); + + isRecording = true; + recordingStartTime = System.currentTimeMillis(); + recordingDuration = 0L; + + // 启动计时器 + timer = new Timer(); + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + if (isRecording) { + recordingDuration = System.currentTimeMillis() - recordingStartTime; + + // 检查是否达到最大录音时间(5分钟) + if (recordingDuration >= 5 * 60 * 1000) { + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(SingerVerificationActivity.this, "已达到最大录音时间5分钟,录音自动停止", Toast.LENGTH_SHORT).show(); + stopRecording(); + } + }); + return; + } + + runOnUiThread(new Runnable() { + @Override + public void run() { + updateUI(); + } + }); + } + } + }, 1000, 1000); + + } catch (IOException e) { + Log.e("SingerVerification", "录音失败: " + e.getMessage()); + Toast.makeText(this, "录音失败: " + e.getMessage() + ",请重试", Toast.LENGTH_SHORT).show(); + // 重置录音状态,允许重新录制 + isRecording = false; + if (mediaRecorder != null) { + mediaRecorder.release(); + mediaRecorder = null; + } + if (recordingFile != null && recordingFile.exists()) { + recordingFile.delete(); + recordingFile = null; + } + updateUI(); + } + } + + // 停止录音 + private void stopRecording() { + try { + if (isRecording && mediaRecorder != null) { + isRecording = false; + mediaRecorder.stop(); + mediaRecorder.release(); + mediaRecorder = null; + + // 取消计时器 + if (timer != null) { + timer.cancel(); + timer = null; + } + + // 检查录音时长是否达到最小要求(60秒) + if (recordingDuration < 60 * 1000) { + Toast.makeText(this, "录音时间太短,请至少录制60秒", Toast.LENGTH_SHORT).show(); + // 删除不符合要求的录音文件 + if (recordingFile != null && recordingFile.exists()) { + recordingFile.delete(); + recordingFile = null; + } + recordingDuration = 0L; + } else { + Toast.makeText(this, "录音完成", Toast.LENGTH_SHORT).show(); + } + + updateUI(); + } + } catch (Exception e) { + Log.e("SingerVerification", "停止录音失败: " + e.getMessage()); + Toast.makeText(this, "停止录音失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); + + // 发生异常时重置状态,允许重新录制 + isRecording = false; + if (mediaRecorder != null) { + mediaRecorder.release(); + mediaRecorder = null; + } + if (recordingFile != null && recordingFile.exists()) { + recordingFile.delete(); + recordingFile = null; + } + recordingDuration = 0L; + updateUI(); + } + } + + // 开始播放 + private void startPlaying() { + if (recordingFile == null || !recordingFile.exists()) { + Toast.makeText(this, "没有录制的文件", Toast.LENGTH_SHORT).show(); + return; + } + + try { + stopRecording(); + + mediaPlayer = new MediaPlayer(); + mediaPlayer.setDataSource(recordingFile.getAbsolutePath()); + mediaPlayer.prepare(); + mediaPlayer.start(); + + mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + @Override + public void onCompletion(MediaPlayer mp) { + isPlaying = false; + + // 恢复按钮状态 + mBinding.playButton.setText("试听"); + mBinding.playButton.setCompoundDrawablesWithIntrinsicBounds(0, R.mipmap.but_st, 0, 0); + + updateUI(); + } + }); + + isPlaying = true; + updateUI(); + } catch (IOException e) { + Log.e("SingerVerification", "播放失败: " + e.getMessage()); + Toast.makeText(this, "播放失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); + } + } + + // 停止播放 + private void stopPlaying() { + try { + if (isPlaying && mediaPlayer != null) { + isPlaying = false; + mediaPlayer.stop(); + mediaPlayer.release(); + mediaPlayer = null; + + // 恢复按钮状态 + mBinding.playButton.setText("试听"); + mBinding.playButton.setCompoundDrawablesWithIntrinsicBounds(0, R.mipmap.but_st, 0, 0); + + updateUI(); + } + } catch (Exception e) { + Log.e("SingerVerification", "停止播放失败: " + e.getMessage()); + Toast.makeText(this, "停止播放失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); + } + } + + // 重新录音 + private void reRecord() { + stopPlaying(); + stopRecording(); + if (recordingFile != null && recordingFile.exists()) { + recordingFile.delete(); + } + recordingFile = null; + recordingDuration = 0L; + updateUI(); + } + + // 提交认证 + private void submitVerification() { + if (recordingFile == null || !recordingFile.exists()) { + Toast.makeText(this, "请先录制音频", Toast.LENGTH_SHORT).show(); + return; + } + + MvpPre.uploadFile(recordingFile, 3); + } + + // 创建音频文件 + private File createAudioFile() throws IOException { + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); + String audioFileName = "AUDIO_" + timeStamp + "_"; + File storageDir = getExternalFilesDir(Environment.DIRECTORY_MUSIC); + + return File.createTempFile( + audioFileName, + ".m4a", + storageDir + ); + } + + // 更新UI + private void updateUI() { + + // 更新时间显示 + mBinding.timeTextView.setText(formatTime(recordingDuration)); + // 计算录音进度(假设最大录音时间为5分钟=300秒) + int maxRecordingTime = 300; // 5分钟 + int progress = (int) ((recordingDuration / 1000) * 100 / maxRecordingTime); + mBinding.progressArc.setProgress(progress); // 更新按钮状态 + } + + // 格式化时间显示 + private String formatTime(long millis) { + long totalSeconds = millis / 1000; + long minutes = totalSeconds / 60; + long seconds = totalSeconds % 60; + return String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (requestCode == REQUEST_RECORD_AUDIO_PERMISSION) { + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + Toast.makeText(this, "录音权限已获取", Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(this, "需要录音权限才能进行认证", Toast.LENGTH_SHORT).show(); + } + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + stopRecording(); + stopPlaying(); + if (timer != null) { + timer.cancel(); + timer = null; + } + } + + @Override + public void upLoadSuccess(String url, int type) { + MvpPre.singerAuth(url); + } + + @Override + public void singerAuth(String s) { + reRecord(); + finish(); + } + + @Override + public void getSong(SongPlaylist s) { + + } + + @Override + public void finishComment() { + + } + + @Override + public void deleteSong() { + + } +} \ No newline at end of file diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/user/activity/UserPlaylistActivity.java b/MainModule/src/main/java/com/xscm/modulemain/activity/user/activity/UserPlaylistActivity.java new file mode 100644 index 00000000..411dd29b --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/user/activity/UserPlaylistActivity.java @@ -0,0 +1,174 @@ +package com.xscm.modulemain.activity.user.activity; + +import android.graphics.Color; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; +import com.xscm.modulemain.adapter.UserPlaylistAdapter; +import com.xscm.modulemain.BaseMvpActivity; +import com.xscm.modulemain.R; +import com.xscm.modulemain.activity.user.conacts.SingerVerificationContract; +import com.xscm.modulemain.activity.user.presenter.SingerVerificationPresenter; +import com.xscm.modulemain.databinding.ActivityUserPlaylistBinding; +import com.xscm.modulemain.dialog.CustomInputDialog; +import com.xscm.moduleutil.bean.SongPlaylist; +import com.xscm.moduleutil.utils.SpUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * 我的歌单 + */ +public class UserPlaylistActivity extends BaseMvpActivity implements SingerVerificationContract.View { + + private int page = 0; + private UserPlaylistAdapter mAdapter; + private List mSongPlaylistBean; + + @Override + protected void initView() { + super.initView(); + mBinding.topBar.setTitle("歌单列表"); + mBinding.topBar.setRightText("新增"); + mBinding.topBar.setRightTxtVisible(true); + mBinding.topBar.setRightColor(Color.parseColor("#3ABC6D")); + mBinding.topBar.getTvRight().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + //新增歌单 + // 在Activity或Fragment中调用 + CustomInputDialog customInputDialog = new CustomInputDialog(UserPlaylistActivity.this); + customInputDialog.show(); + } + }); + mBinding.recycleView.setLayoutManager(new LinearLayoutManager(this)); + + // 初始化适配器 + mAdapter = new UserPlaylistAdapter(this, new ArrayList<>()); + mBinding.recycleView.setAdapter(mAdapter); + // 设置滑动操作 +// ItemTouchHelper itemTouchHelper = UserPlaylistAdapter.getItemTouchHelper(mAdapter); +// itemTouchHelper.attachToRecyclerView(mBinding.recycleView); + + + // 设置编辑点击事件 + mAdapter.setOnEditClickListener(position -> { + // 处理编辑点击事件 + CustomInputDialog customInputDialog = new CustomInputDialog(UserPlaylistActivity.this); + customInputDialog.PlaylistBean(mSongPlaylistBean.get(position)); + customInputDialog.setOnDialogDismissListener(new CustomInputDialog.OnDialogDismissListener() { + @Override + public void onDialogDismiss(boolean dataChanged) { + if (dataChanged) + // 数据已更改,重新加载数据 + page = 1; + MvpPre.getSong(SpUtil.getUserId() + "", "", page + "", "10"); + } + }); + customInputDialog.show(); + + + }); + + // 设置删除点击事件 + mAdapter.setOnDeleteClickListener(position -> { + // 处理删除点击事件 + MvpPre.deleteSong(mSongPlaylistBean.get(position).getId() + ""); + + }); + + mBinding.smartRefreshLayout.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + page++; + MvpPre.getSong(SpUtil.getUserId() + "", "", page + "", "10"); + } + + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { +// EventBus.getDefault().post(new BannerRefreshEvent()); + page = 1; + MvpPre.getSong(SpUtil.getUserId() + "", "", page + "", "10"); + } + }); + } + + @Override + protected void initData() { + + } + + @Override + protected void onResume() { + super.onResume(); + page = 1; + MvpPre.getSong(SpUtil.getUserId() + "", "", page + "", "10"); + } + + @Override + protected int getLayoutId() { + return R.layout.activity_user_playlist; + } + + @Override + protected SingerVerificationPresenter bindPresenter() { + return new SingerVerificationPresenter(this, this); + } + + @Override + public void upLoadSuccess(String url, int type) { + + } + + @Override + public void singerAuth(String s) { + + } + + @Override + public void getSong(SongPlaylist s) { + if (mAdapter != null) { + if (page == 1) { + // 第一页,直接设置数据 + if (s == null || s.getLists() == null || s.getLists().size() == 0) { + return; + } + mSongPlaylistBean = s.getLists(); + mAdapter.setNewData(s.getLists()); + } else { + if (s == null || s.getLists() == null || s.getLists().size() == 0) { + return; + } + mSongPlaylistBean.addAll(s.getLists()); + // 更多页面,添加数据 + mAdapter.addData(s.getLists()); + } + + // 更新歌单数量 + mBinding.tvNum.setText("共" + s.getCount() + "首歌"); + } + + // 结束刷新或加载更多 + if (mBinding.smartRefreshLayout != null) { + mBinding.smartRefreshLayout.finishRefresh(); + mBinding.smartRefreshLayout.finishLoadMore(); + } + } + + @Override + public void finishComment() { + mBinding.smartRefreshLayout.finishRefresh(); + mBinding.smartRefreshLayout.finishLoadMore(); + } + + @Override + public void deleteSong() { + page = 1; + MvpPre.getSong(SpUtil.getUserId() + "", "", page + "", "10"); + } +} \ No newline at end of file diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/user/conacts/SingerVerificationContract.java b/MainModule/src/main/java/com/xscm/modulemain/activity/user/conacts/SingerVerificationContract.java new file mode 100644 index 00000000..88a8aa78 --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/user/conacts/SingerVerificationContract.java @@ -0,0 +1,43 @@ +package com.xscm.modulemain.activity.user.conacts; + +import android.app.Activity; + +import com.xscm.moduleutil.activity.IPresenter; +import com.xscm.moduleutil.activity.IView; +import com.xscm.moduleutil.bean.SongPlaylist; + +import java.io.File; + +/** + * 歌手验证合约类,定义了歌手验证功能所需的视图和 presenter 接口 + * 该类采用了合约模式,将视图和 presenter 的接口定义在一起,便于维护 + */ +public class SingerVerificationContract { + /** + * 歌手验证视图接口,继承自 IView + * 该接口定义了歌手验证功能所需的视图层方法 + */ + public interface View extends IView { + void upLoadSuccess(String url, int type); + void singerAuth(String s); + void getSong(SongPlaylist s); + + void finishComment(); + + void deleteSong(); + } + + /** + * 歌手验证的 presenter 接口,继承自 IPresenter + * 该接口定义了歌手验证功能所需的 presenter 层方法 + */ + public interface IMePre extends IPresenter { + void uploadFile(File file, int type); + + void singerAuth(String url); + + void getSong(String userId,String roomId,String page,String pageSize); + + void deleteSong(String songId); + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/user/fragment/VocalRangeFragment.java b/MainModule/src/main/java/com/xscm/modulemain/activity/user/fragment/VocalRangeFragment.java index 1394a3f7..e5f35ce9 100644 --- a/MainModule/src/main/java/com/xscm/modulemain/activity/user/fragment/VocalRangeFragment.java +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/user/fragment/VocalRangeFragment.java @@ -24,6 +24,8 @@ import com.xscm.modulemain.R; import com.xscm.modulemain.activity.user.activity.GiftWallActivity; import com.xscm.modulemain.activity.user.activity.NobleTitleActivity; import com.xscm.modulemain.activity.user.activity.RechargeActivity; +import com.xscm.modulemain.activity.user.activity.SingerVerificationActivity; +import com.xscm.modulemain.activity.user.activity.UserPlaylistActivity; import com.xscm.modulemain.databinding.FragmentVocalRangeBinding; import com.xscm.modulemain.activity.user.activity.BlacklistActivity; import com.xscm.modulemain.activity.user.activity.DailyTasksActivity; @@ -54,7 +56,7 @@ import java.util.List; */ public class VocalRangeFragment extends BaseMvpFragment implements MeConacts.View { -// private MyInfoResp mMyInfoResp; + // private MyInfoResp mMyInfoResp; private UserInfo userInfo; public static VocalRangeFragment newInstance() { @@ -84,7 +86,6 @@ public class VocalRangeFragment extends BaseMvpFragment=20){ - Intent intent=new Intent(getContext(), BlacklistActivity.class); - intent.putExtra("type",3); - startActivity(intent); + Intent intent = new Intent(getContext(), BlacklistActivity.class); + intent.putExtra("type", 3); + startActivity(intent); // }else { // ToastUtils.showShort("需要魅力等级20以上才能查看"); // } // ARouter.getInstance().build(ARouteConstants.ME_MY_FRIENDS).withInt("type", 0).navigation(); // AppLogUtil.reportAppLog(AppLogEvent.C0112); - } - else if (id == R.id.im_my_room) { + } else if (id == R.id.im_my_room) { //我的房间 startActivity(new Intent(getContext(), MyRoomActivity.class)); - } else if (id == R.id.tv_nick_name || id == R.id.tv_home) {//编辑信息 + } else if (id == R.id.tv_nick_name || id == R.id.tv_home) {//编辑信息 startActivity(new Intent(getContext(), EditUserInfoActivity.class)); - }else if (id == R.id.tv_my_wallet){//钱包 + } else if (id == R.id.tv_my_wallet) {//钱包 startActivity(new Intent(getContext(), MyMoneyActivity.class)); - }else if (id == R.id.riv_user_head ){//用户主页 + } else if (id == R.id.riv_user_head) {//用户主页 Intent intent = new Intent(getContext(), UserHomepageActivity.class); - intent.putExtra("userId",SpUtil.getUserId()+""); + intent.putExtra("userId", SpUtil.getUserId() + ""); startActivity(intent); } // else if (id == R.id.me_my_lv) { @@ -220,42 +225,44 @@ public class VocalRangeFragment extends BaseMvpFragmentcopyUserId(data.getUser_code())); -// mBinding.rivUserHead.setData(data.getHead_picture(), data.getRank_info().getPicture(), data.getSex()); -// } - @Override public void myInfoSuccess(UserInfo data) { SpUtil.saveUserInfo(data); this.userInfo = data; - mBinding.rivUserHead.setData(data.getAvatar(), data.getDress(),data.getNobility_image()); + mBinding.rivUserHead.setData(data.getAvatar(), data.getDress(), data.getNobility_image()); mBinding.tvNickName.setText(data.getNickname()); + mBinding.tvNickName.setTextColor((data.getNickname_color() != null && !data.getNickname_color().equals("")) ? Color.parseColor(data.getNickname_color()) : Color.parseColor("#ffffff")); + String sex = data.getSex() == 1 ? "男" : "女"; + mBinding.beautifulView.setText(sex + " | ID:" + data.getUser_code()); + mBinding.tvFollow.setText(data.getFollow_num() + ""); + mBinding.tvFans.setText(data.getFans_num() + ""); + mBinding.tvFriends.setText(data.getLook_me_num() + ""); - - if (!data.getNickname_color().isEmpty()){ - mBinding.tvNickName.setStartColor(Color.parseColor(data.getNickname_color())); - mBinding.tvNickName.setShineColor(Color.parseColor(data.getNickname_color())); - mBinding.tvNickName.setEndColor(Color.parseColor(data.getNickname_color())); - mBinding.tvNickName.setShine(true); - mBinding.tvNickName.setShineType(0); - } - -// mBinding.tvNickName.setTextColor( (data.getNickname_color()!=null&& !data.getNickname_color().equals(""))? Color.parseColor(data.getNickname_color()): Color.parseColor("#ffffff")); - String sex = data.getSex()==1?"男":"女"; - mBinding.beautifulView.setText(sex+" | ID:"+data.getUser_code()); - mBinding.tvFollow.setText(data.getFollow_num()+""); - mBinding.tvFans.setText(data.getFans_num()+""); - mBinding.tvFriends.setText(data.getLook_me_num()+""); - - if (data.getIs_use_code()==1){ + if (data.getIs_use_code() == 1) { mBinding.imBeautiful.setVisibility(View.VISIBLE); - }else { + } else { mBinding.imBeautiful.setVisibility(View.GONE); } - if (data.getAuth()==1){ + if (data.getAuth() == 1) { SpUtil.setRealName(true); - }else { + } else { SpUtil.setRealName(false); } @@ -369,6 +347,14 @@ public class VocalRangeFragment extends BaseMvpFragment implements SingerVerificationContract.IMePre { + // 视图接口对象,用于与View层交互 + SingerVerificationContract.View mView; + + /** + * 构造函数,初始化Presenter + * + * @param view 视图接口对象,用于与View层交互 + * @param context 上下文对象,用于获取系统资源等 + */ + public SingerVerificationPresenter(SingerVerificationContract.View view, Context context) { + super(view, context); // 调用父类构造函数 + mView = view; // 保存视图接口对象的引用 + } + + @Override + public void uploadFile(File file, int type) { + String fileMD5 = Md5Utils.getFileMD5(file); + String suffix = ""; + if (file.getName().contains(".")) { + suffix = file.getName().substring(file.getName().lastIndexOf(".")); + } + String url = "audio/" + fileMD5 + suffix; + CosUploadManager.getInstance(CommonAppContext.getInstance()).upParameters(url, file.getPath(), new CosUploadManager.UploadCallback() { + @Override + public void onSuccess(String url) { + if (MvpRef == null) { + MvpRef = new WeakReference<>(mView); + } + MvpRef.get().upLoadSuccess(url, type); + + } + + @Override + public void onFailure(Exception e) { + ToastUtils.show("上传失败"); + } + + @Override + public void onFailure1(IllegalStateException e) { + ToastUtils.show("上传失败"); + } + + + }); + } + + @Override + public void singerAuth(String url) { + api.singerAuth(url, new BaseObserver() { + + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(String s) { + if (MvpRef == null) { + MvpRef = new WeakReference<>(mView); + } + MvpRef.get().singerAuth(s); + } + }); + } + + @Override + public void getSong(String userId, String roomId, String page, String pageSize) { + api.getSong(userId, roomId, page, pageSize, new BaseObserver() { + + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(SongPlaylist songPlaylist) { + if (MvpRef == null) { + MvpRef = new WeakReference<>(mView); + } + MvpRef.get().getSong(songPlaylist); + MvpRef.get().finishComment(); + } + }); + } + + @Override + public void deleteSong(String songId) { + api.deleteSong(songId, new BaseObserver() { + + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(String s) { + if (MvpRef == null) { + MvpRef = new WeakReference<>(mView); + } + MvpRef.get().deleteSong(); + } + }); + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/adapter/UserPlaylistAdapter.java b/MainModule/src/main/java/com/xscm/modulemain/adapter/UserPlaylistAdapter.java new file mode 100644 index 00000000..5d52ff64 --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/adapter/UserPlaylistAdapter.java @@ -0,0 +1,102 @@ +package com.xscm.modulemain.adapter; + +import android.content.Context; +import android.app.AlertDialog; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.BaseViewHolder; + +import com.xscm.modulemain.R; +import com.xscm.moduleutil.bean.SongPlaylist; +import com.xscm.moduleutil.utils.ImageUtils; + +import java.util.List; + +/** + * 用户歌单适配器,支持长按显示编辑和删除选项 + */ +public class UserPlaylistAdapter extends BaseQuickAdapter { + + private OnItemClickListener mOnItemClickListener; + private OnEditClickListener mOnEditClickListener; + private OnDeleteClickListener mOnDeleteClickListener; + + public UserPlaylistAdapter(Context context, List data) { + super(R.layout.item_user_playlist, data); + this.mContext = context; + } + + /** + * 显示选项对话框 + */ + private void showOptionsDialog(int position) { + if (position < 0 || position >= getData().size()) { + return; + } + String[] options = {"编辑", "删除"}; + AlertDialog.Builder builder = new AlertDialog.Builder(mContext); + builder.setTitle("选择操作") + .setItems(options, (dialog, which) -> { + switch (which) { + case 0: // 编辑 + if (mOnEditClickListener != null) { + mOnEditClickListener.onEditClick(position); + } + break; + case 1: // 删除 + if (mOnDeleteClickListener != null) { + mOnDeleteClickListener.onDeleteClick(position); + } + break; + } + }) + .show(); + } + + @Override + protected void convert(BaseViewHolder helper, SongPlaylist.SongPlaylistBean item) { + helper.setText(R.id.tv_song_name,item.getSong_name()).setText(R.id.tv_count,"x"+item.getGift_num()) + .setText(R.id.tv_gift_name,item.getGift_name()) + .setText(R.id.tv_gift_value,item.getGift_price()); + ImageUtils.loadHeadCC(item.getBase_image(),helper.getView(R.id.iv_gift)); + + // 设置点击事件 + helper.itemView.setOnClickListener(v -> { + if (mOnItemClickListener != null) { + mOnItemClickListener.onItemClick(helper.getAdapterPosition()); + } + }); + + // 设置长按事件 + helper.itemView.setOnLongClickListener(v -> { + showOptionsDialog(helper.getLayoutPosition()); + return true; + }); + } + + public void setOnItemClickListener(OnItemClickListener listener) { + this.mOnItemClickListener = listener; + } + + public void setOnEditClickListener(OnEditClickListener listener) { + this.mOnEditClickListener = listener; + } + + public void setOnDeleteClickListener(OnDeleteClickListener listener) { + this.mOnDeleteClickListener = listener; + } + + public interface OnItemClickListener { + void onItemClick(int position); + } + + public interface OnEditClickListener { + void onEditClick(int position); + } + + public interface OnDeleteClickListener { + void onDeleteClick(int position); + } + + // 移除了ItemTouchHelper相关代码,因为不再需要滑动操作 +} \ No newline at end of file diff --git a/MainModule/src/main/java/com/xscm/modulemain/dialog/CustomInputDialog.java b/MainModule/src/main/java/com/xscm/modulemain/dialog/CustomInputDialog.java new file mode 100644 index 00000000..ceafdb42 --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/dialog/CustomInputDialog.java @@ -0,0 +1,161 @@ +package com.xscm.modulemain.dialog; + +import android.content.Context; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; + +import com.blankj.utilcode.util.ScreenUtils; +import com.blankj.utilcode.util.ToastUtils; +import com.blankj.utilcode.util.TouchUtils; +import com.xscm.modulemain.R; +import com.xscm.modulemain.databinding.DialogCustomInputBinding; +import com.xscm.moduleutil.bean.RoonGiftModel; +import com.xscm.moduleutil.bean.SongPlaylist; +import com.xscm.moduleutil.event.GiftUserRefreshEvent; +import com.xscm.moduleutil.event.RoomGiftClickToEvent; +import com.xscm.moduleutil.http.BaseObserver; +import com.xscm.moduleutil.http.RetrofitClient; +import com.xscm.moduleutil.widget.dialog.BaseDialog; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import io.reactivex.disposables.Disposable; + +/** + * 自定义输入对话框 + */ +public class CustomInputDialog extends BaseDialog { + + GiftSongDialog giftSongDialog; + private String mGiftId, mGiftNum; + private SongPlaylist.SongPlaylistBean mSongPlaylistBean; + private OnDialogDismissListener mListener; + + public CustomInputDialog(@NonNull Context context) { + super(context); + } + + // 设置监听器 + public void setOnDialogDismissListener(OnDialogDismissListener listener) { + this.mListener = listener; + } + + // 定义回调接口 + public interface OnDialogDismissListener { + void onDialogDismiss(boolean dataChanged); + } + + @Override + public int getLayoutId() { + return R.layout.dialog_custom_input; + } + + @Override + public void initView() { + setCancelable(false); + setCanceledOnTouchOutside(false); + Window window = getWindow(); + window.setLayout((int) (ScreenUtils.getScreenWidth() * 315.f / 375), WindowManager.LayoutParams.WRAP_CONTENT); + mBinding.ivClose.setOnClickListener(v -> dismiss()); + + } + + @Override + public void initData() { + + + mBinding.ivClose.setOnClickListener(v -> { + dismiss(); + // 通知Activity对话框关闭,但数据未更改 + if (mListener != null) { + mListener.onDialogDismiss(false); + } + }); + + mBinding.tvCancel.setOnClickListener(v -> { + dismiss(); + // 通知Activity对话框关闭,但数据未更改 + if (mListener != null) { + mListener.onDialogDismiss(false); + } + }); + mBinding.tvClickable.setOnClickListener(v -> { + giftSongDialog = new GiftSongDialog(getContext()); + giftSongDialog.show(); + giftSongDialog.setOnGiftConfirmListener(new GiftSongDialog.OnGiftConfirmListener() { + @Override + public void onGiftConfirm(String giftId, String name, String giftNum) { + mGiftId = giftId; + mGiftNum = giftNum; + mBinding.tvClickable.setText(name); + } + }); + + }); + + + mBinding.tvConfirm.setOnClickListener(v -> { + if (mBinding.etInput.getText().toString().isEmpty()) { + ToastUtils.showLong("请输入歌曲名称"); + return; + } + if (mBinding.tvClickable.getText().toString().isEmpty()) { + ToastUtils.showLong("请选择礼物"); + return; + } + if (mSongPlaylistBean != null) { + RetrofitClient.getInstance().singerUpdateSong(mSongPlaylistBean.getId() + "", mBinding.etInput.getText().toString(), mGiftId, mGiftNum, new BaseObserver() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(String s) { + dismiss(); + // 通知Activity数据已更新 + if (mListener != null) { + mListener.onDialogDismiss(true); + } + } + }); + } else { + RetrofitClient.getInstance().singerAddSong(mBinding.etInput.getText().toString(), mGiftId, mGiftNum, new BaseObserver() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(String s) { + dismiss(); + // 通知Activity数据已更新 + if (mListener != null) { + mListener.onDialogDismiss(true); + } + } + }); + } + + }); + + } + + public void PlaylistBean(SongPlaylist.SongPlaylistBean songPlaylistBean) { + this.mSongPlaylistBean = songPlaylistBean; + setPlaylistBean(); + } + + private void setPlaylistBean() { + if (mSongPlaylistBean != null) { + mBinding.etInput.setText(mSongPlaylistBean.getSong_name()); + mBinding.tvClickable.setText(mSongPlaylistBean.getGift_name()); + mGiftId=mSongPlaylistBean.getGift_id(); + mGiftNum=mSongPlaylistBean.getGift_num(); + } + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/dialog/GiftSongDialog.java b/MainModule/src/main/java/com/xscm/modulemain/dialog/GiftSongDialog.java new file mode 100644 index 00000000..aeede20a --- /dev/null +++ b/MainModule/src/main/java/com/xscm/modulemain/dialog/GiftSongDialog.java @@ -0,0 +1,173 @@ +package com.xscm.modulemain.dialog; + +import android.content.Context; +import android.view.Gravity; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; + +import com.blankj.utilcode.util.ScreenUtils; +import com.xscm.modulemain.R; +import com.xscm.modulemain.databinding.DialogGiftSongBinding; +import com.xscm.moduleutil.adapter.GiftRoomAdapter; +import com.xscm.moduleutil.base.BaseFragment; +import com.xscm.moduleutil.base.CommonAppContext; +import com.xscm.moduleutil.bean.GiftNumBean; +import com.xscm.moduleutil.bean.RoonGiftModel; +import com.xscm.moduleutil.event.GiftUserRefreshEvent; +import com.xscm.moduleutil.event.RoomGiftClickToEvent; +import com.xscm.moduleutil.http.BaseObserver; +import com.xscm.moduleutil.http.RetrofitClient; +import com.xscm.moduleutil.widget.dialog.BaseDialog; +import com.xscm.moduleutil.widget.dialog.KeyboardPopupWindow; +import com.xscm.moduleutil.widget.dialog.SelectGiftNumPopupWindow; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.ArrayList; +import java.util.List; + +import io.reactivex.disposables.Disposable; + +/** + * 礼物歌曲对话框类 + * 该类可能用于实现一个展示歌曲相关礼物的对话框界面 + */ +public class GiftSongDialog extends BaseDialog { + private GiftRoomAdapter roomAdapter; + private List mGiftNumList; + private SelectGiftNumPopupWindow mSelectGiftNumPopupWindow; + private KeyboardPopupWindow mKeyboardPopupWindow; + + private List giftList = new ArrayList<>(); + private OnGiftConfirmListener onGiftConfirmListener; + + public GiftSongDialog(@NonNull Context context) { + super(context, com.xscm.moduleutil.R.style.dialogBottom); + } + + public interface OnGiftConfirmListener { + void onGiftConfirm(String giftId,String name, String giftNum); + } + + public void setOnGiftConfirmListener(OnGiftConfirmListener listener) { + this.onGiftConfirmListener = listener; + } + + + @Override + public int getLayoutId() { + return R.layout.dialog_gift_song; + } + + @Override + public void initView() { + EventBus.getDefault().register(this); + setCancelable(true); + setCanceledOnTouchOutside(true); + Window window = getWindow(); + window.setGravity(Gravity.BOTTOM); + window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT); + mBinding.tvGiveCoinNum.setOnClickListener(this::onClick); + mBinding.tvGive.setOnClickListener(this::onClick); + } + + + + private void onClick(View view1) { + if (view1.getId()== com.xscm.moduleutil.R.id.tv_give_coin_num){ + if (mSelectGiftNumPopupWindow == null) { + + mSelectGiftNumPopupWindow = new SelectGiftNumPopupWindow(getContext(), (adapter, view, position) -> { + GiftNumBean giftNumBean = (GiftNumBean) adapter.getItem(position); + if ("0".equals(giftNumBean.getNumber())) {//自定义 + mKeyboardPopupWindow = new KeyboardPopupWindow(getContext(), getCurrentFocus()); + mKeyboardPopupWindow.refreshKeyboardOutSideTouchable(false);//false开启键盘 ,true关闭键盘 + mKeyboardPopupWindow.addRoomPasswordListener(new KeyboardPopupWindow.KeyboardCompleteListener() {//监听自定键盘的完成 + @Override + public void inputComplete(String inputContent) { + mBinding.tvGiveCoinNum.setText(inputContent); + mKeyboardPopupWindow.releaseResources(); + } + }); + } else { + mBinding.tvGiveCoinNum.setText(giftNumBean.getNumber()); + } + mSelectGiftNumPopupWindow.dismiss(); + }); + } + mSelectGiftNumPopupWindow.setData(mGiftNumList); + mSelectGiftNumPopupWindow.showAtLocation(mBinding.tvGiveCoinNum, Gravity.BOTTOM | Gravity.RIGHT, 100, 230); + + }else if (view1.getId()== com.xscm.moduleutil.R.id.tv_give){ + // 获取选中的礼物ID + String selectedGiftId = null; + String name=""; + for (RoonGiftModel giftModel : giftList) { + if (giftModel.isChecked()) { + selectedGiftId = giftModel.getGift_id(); + name=giftModel.getGift_name(); + break; + } + } + + // 获取礼物数量 + String giftNum = mBinding.tvGiveCoinNum.getText().toString(); + + // 如果有选中的礼物,通过回调传递数据 + if (selectedGiftId != null && onGiftConfirmListener != null) { + onGiftConfirmListener.onGiftConfirm(selectedGiftId,name, giftNum); + dismiss(); + } + } + } + + @Override + public void initData() { + mGiftNumList=new ArrayList<>(); + mGiftNumList.add(new GiftNumBean("20", "x20")); + mGiftNumList.add(new GiftNumBean("15", "x15")); + mGiftNumList.add(new GiftNumBean("10", "x10")); + mGiftNumList.add(new GiftNumBean("5", "x5")); + mGiftNumList.add(new GiftNumBean("1", "x1")); + + RetrofitClient.getInstance().getGiftList(0,"",new BaseObserver>() { + + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(List roonGiftModels) { + giftList= roonGiftModels; + roomAdapter = new GiftRoomAdapter(CommonAppContext.getInstance(), roonGiftModels, 0, "0"); + mBinding.rvGift.setAdapter(roomAdapter); + } + }); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onGiftClicRoomkTEvent(RoomGiftClickToEvent event) { + String id = event.gift.getGift_id(); + for (int i = 0; i < giftList.size(); i++) { + RoonGiftModel giftModel = giftList.get(i); + if (giftModel.getGift_id().equals(id)) { + if (giftModel.isChecked()) { + giftModel.setChecked(false); + } else { + giftModel.setChecked(true); + } + } else { + giftModel.setChecked(false); + } + } + if (event.adapter != null && event.adapter.get() != null) { + event.adapter.get().notifyDataSetChanged(); + } + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/dialog/RoomSettingFragment.java b/MainModule/src/main/java/com/xscm/modulemain/dialog/RoomSettingFragment.java index 2ff55a3f..ebf4ea7b 100644 --- a/MainModule/src/main/java/com/xscm/modulemain/dialog/RoomSettingFragment.java +++ b/MainModule/src/main/java/com/xscm/modulemain/dialog/RoomSettingFragment.java @@ -136,12 +136,12 @@ public class RoomSettingFragment extends BaseMvpDialogFragment { @@ -361,7 +361,7 @@ public class RoomSettingFragment extends BaseMvpDialogFragment + + + + + + diff --git a/MainModule/src/main/res/drawable/circular_progress_drawable.xml b/MainModule/src/main/res/drawable/circular_progress_drawable.xml new file mode 100644 index 00000000..398f76fe --- /dev/null +++ b/MainModule/src/main/res/drawable/circular_progress_drawable.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MainModule/src/main/res/layout/activity_singer_verification.xml b/MainModule/src/main/res/layout/activity_singer_verification.xml new file mode 100644 index 00000000..94758bcd --- /dev/null +++ b/MainModule/src/main/res/layout/activity_singer_verification.xml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +