合并1
BIN
BaseModule/src/main/assets/mic.svga
Normal file
@@ -168,7 +168,7 @@ public class CirleListAdapter extends BaseQuickAdapter<CircleListBean, BaseViewH
|
||||
//头像
|
||||
// ImageUtils.loadHeadCC(item.getAvatar(), helper.getView(R.id.dy_head_image));
|
||||
MeHeadView headView = helper.getView(R.id.dy_head_image);
|
||||
headView.setData(item.getAvatar(), "", item.getSex() + "");
|
||||
headView.setData(item.getAvatar(), "", item.getNobility_image());
|
||||
//动态内容以富文本展示
|
||||
String content = item.getContent();
|
||||
if (content == null || content.length() == 0) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.xscm.moduleutil.adapter;
|
||||
|
||||
import static android.view.View.GONE;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.text.Spannable;
|
||||
@@ -16,6 +18,7 @@ import android.widget.TextView;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.hjq.toast.ToastUtils;
|
||||
import com.xscm.moduleutil.R;
|
||||
import com.xscm.moduleutil.bean.RoonGiftModel;
|
||||
import com.xscm.moduleutil.event.RoomGiftClickToEvent;
|
||||
@@ -111,38 +114,6 @@ public class GiftRoomAdapter extends BaseAdapter {
|
||||
}
|
||||
|
||||
|
||||
// private static class MyGestureDetector extends GestureDetector {
|
||||
// private GiftRoomAdapter mAdapter;
|
||||
// private RoonGiftModel mGiftModel;
|
||||
//
|
||||
// public MyGestureDetector(Context context) {
|
||||
// super(context, new SimpleOnGestureListener() {
|
||||
// @Override
|
||||
// public boolean onSingleTapConfirmed(MotionEvent e) {
|
||||
// if (mAdapter != null && mGiftModel != null) {
|
||||
// EventBus.getDefault().post(new RoomGiftClickToEvent(mAdapter, mGiftModel, 1));
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean onDoubleTap(MotionEvent e) {
|
||||
// if (mAdapter != null && mGiftModel != null) {
|
||||
// EventBus.getDefault().post(new RoomGiftClickToEvent(mAdapter, mGiftModel, 2));
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// });
|
||||
// setOnDoubleTapListener(getListener());
|
||||
// }
|
||||
//
|
||||
// public void setGiftModel(GiftRoomAdapter adapter, RoonGiftModel giftModel) {
|
||||
// this.mAdapter = adapter;
|
||||
// this.mGiftModel = giftModel;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressLint({"SetTextI18n", "ClickableViewAccessibility"})
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
@@ -157,6 +128,7 @@ public class GiftRoomAdapter extends BaseAdapter {
|
||||
viewHolder.item_layout = (ConstraintLayout) convertView.findViewById(R.id.cl_gift);
|
||||
viewHolder.ivDownOn = (ImageView) convertView.findViewById(R.id.iv_down_on);
|
||||
viewHolder.cl_iv_down_on = (ConstraintLayout) convertView.findViewById(R.id.cl_iv_down_on);
|
||||
viewHolder.iv_gift_select= (ImageView) convertView.findViewById(R.id.iv_gift_select);
|
||||
|
||||
convertView.setTag(viewHolder);
|
||||
} else {
|
||||
@@ -165,10 +137,17 @@ public class GiftRoomAdapter extends BaseAdapter {
|
||||
|
||||
viewHolder.item_layout.setOnClickListener(v -> {
|
||||
// RoonGiftModel clickedModel = (RoonGiftModel) v.getTag();
|
||||
if (giftModel.getIs_lock()==0) {
|
||||
EventBus.getDefault().post(new RoomGiftClickToEvent(this, giftModel, 1));
|
||||
|
||||
}else if (giftModel.getIs_lock()==1){
|
||||
ToastUtils.show("当前属于爵位礼物,请开通爵位");
|
||||
}
|
||||
});
|
||||
|
||||
if (giftModel.getIs_lock()==0){
|
||||
viewHolder.iv_gift_select.setVisibility(GONE);
|
||||
}else {
|
||||
viewHolder.iv_gift_select.setVisibility(View.VISIBLE);
|
||||
}
|
||||
/*
|
||||
* 在给View绑定显示的数据时,计算正确的position = position + curIndex * pageSize,
|
||||
*/
|
||||
@@ -234,6 +213,7 @@ public class GiftRoomAdapter extends BaseAdapter {
|
||||
public ImageView iv_gift_pic;
|
||||
public TextView tv_gift_change_love_values;
|
||||
public ImageView ivDownOn;
|
||||
public ImageView iv_gift_select;
|
||||
public ConstraintLayout cl_iv_down_on;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,12 +159,10 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio
|
||||
adjustFontScale(getResources().getConfiguration());
|
||||
CrashHandler.init(this);
|
||||
|
||||
if (currentEnvironment.getShelf()==1){
|
||||
if (SpUtil.getShelf()!=1) {
|
||||
if (SpUtil.getShelf()!=0) {
|
||||
SpUtil.setShelf(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void adjustFontScale(Configuration configuration) {
|
||||
if (configuration.fontScale != 1.0f) {
|
||||
@@ -437,8 +435,7 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio
|
||||
if (SpUtil.isAgreePolicy()) {
|
||||
checkInEmulator();
|
||||
// UtilConfig.checkInEmulator();
|
||||
AgoraManager.getInstance(this);
|
||||
AgoraManager.init(currentEnvironment.getSwSdkAppId());
|
||||
AgoraManager.getInstance();
|
||||
MessageListenerSingleton.getInstance();
|
||||
CrashReport.initCrashReport(this, "b45883f58f", true);/*bugly初始化*/
|
||||
// // 启动 MQTT 服务
|
||||
@@ -763,7 +760,7 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio
|
||||
// piaoPingManager.unsubscribe();
|
||||
FileUtils.deleteAllInDir(getCacheDir());
|
||||
FileUtils.deleteAllInDir(getExternalCacheDir());
|
||||
AgoraManager.getInstance(getApplicationContext()).destroy();
|
||||
AgoraManager.getInstance().destroy();
|
||||
// 每次启动应用时重置状态
|
||||
SpUtil.setBooleanValue("youth_model_shown", false);
|
||||
|
||||
|
||||
@@ -31,19 +31,23 @@ public class CircleListBean {
|
||||
public String share_url;
|
||||
public List<HeatedBean> title;//话题列表
|
||||
|
||||
public String nobility_image;//贵族图标
|
||||
public String nickname_color;//昵称颜色
|
||||
public String mic_cycle;//麦圈
|
||||
|
||||
public String read_num;//阅读数
|
||||
public List<LikeList> like_list;
|
||||
|
||||
|
||||
@Data
|
||||
public class LikeList {
|
||||
private String user_id;
|
||||
private String nickname;
|
||||
private String avatar;
|
||||
private int age;//年龄
|
||||
private String sex;
|
||||
private String constellation;//星座
|
||||
private String birthday;//生日
|
||||
public String user_id;
|
||||
public String nickname;
|
||||
public String avatar;
|
||||
public int age;//年龄
|
||||
public String sex;
|
||||
public String constellation;//星座
|
||||
public String birthday;//生日
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,5 +20,6 @@ public class ExpandColumnBean {
|
||||
private int room_id;//房间id,当有参数的时候,就显示跟随,当没有的时候,就显示私信控件
|
||||
private String agree;
|
||||
private List<String> icon;
|
||||
|
||||
private String nobility_image;//贵族图标
|
||||
private String nickname_color;//昵称颜色
|
||||
}
|
||||
|
||||
@@ -25,4 +25,8 @@ public class MusicSongBean implements Serializable {
|
||||
private String dress;
|
||||
private String charm;
|
||||
private int is_hot;//是否是主持,并且是在9号麦位上
|
||||
|
||||
private String nobility_image;//贵族图标
|
||||
private String nickname_color;//昵称颜色
|
||||
private String mic_cycle;//麦圈
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
*com.xscm.moduleutil.bean
|
||||
*qx
|
||||
*2025/11/8
|
||||
*
|
||||
*/
|
||||
class NobilitDeatils {
|
||||
|
||||
var nobility_power_list = ArrayList<nobilityPowerItem>()
|
||||
var user_info: UserInfo? = null
|
||||
var nobility_info: NobilityInfo? = null
|
||||
|
||||
class UserInfo {
|
||||
/*"user_info": { // 用户信息
|
||||
"id": 20034, //用户Id
|
||||
"nickname": "奋斗的石头", //用户昵称
|
||||
"avatar": "http://test.vespa.qxyushen.top/data/avatar/head_pic.png" //用户头像
|
||||
}*/
|
||||
var id: Int = 0
|
||||
var nickname: String = ""
|
||||
var avatar: String = ""
|
||||
}
|
||||
|
||||
class NobilityInfo {
|
||||
/*"nobility_info": { // 爵位信息
|
||||
"status": 0, //状态: 0去开通 1去续费
|
||||
"lid": 0, //爵位ID
|
||||
"name": "", // 爵位名称
|
||||
"image": "", //爵位图片
|
||||
"end_time": 0 //结束时间
|
||||
}*/
|
||||
var status: Int = 0
|
||||
var name: String = ""
|
||||
var lid: Int = 0
|
||||
var image: String = ""
|
||||
var end_time: String = ""
|
||||
}
|
||||
|
||||
class nobilityPowerItem {
|
||||
/*"lid": 0, //爵位ID
|
||||
"name": "特权", //爵位名称
|
||||
"power_ids": "", //权限ID
|
||||
"nick_name_color": "无", //昵称颜色
|
||||
"nick_name_color_name": "无", //昵称颜色名称
|
||||
"nobility_list": [
|
||||
{
|
||||
"id": 1, //权限ID
|
||||
"name": "专属徽章", //权限名称
|
||||
"image": "", //权限图片
|
||||
"status": 0 //权限状态 : 0 不显示 1显示
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "昵称颜色",
|
||||
"image": "",
|
||||
"status": 0
|
||||
}
|
||||
|
||||
]*/
|
||||
|
||||
var lid: Int = 0
|
||||
var name: String = ""
|
||||
var power_ids: String = ""
|
||||
var nick_name_color: String = ""
|
||||
var nick_name_color_name: String = ""
|
||||
var nobility_list = ArrayList<nobilityPowerItem>()
|
||||
|
||||
class nobilityPowerItem {
|
||||
/*"id": 1, //权限ID
|
||||
"name": "专属徽章", //权限名称
|
||||
"image": "", //权限图片
|
||||
"status": 0 //权限状态 : 0 不显示 1显示*/
|
||||
var id: Int = 0
|
||||
var name: String = ""
|
||||
var image: String = ""
|
||||
var status: Int = 0
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
*com.xscm.moduleutil.bean
|
||||
*qx
|
||||
*2025/11/10
|
||||
*
|
||||
*/
|
||||
class NobilitList {
|
||||
|
||||
var name: String = ""
|
||||
var image: String = ""
|
||||
var pay_price: String = ""
|
||||
var power: Power? = Power()
|
||||
var lid: Int = 0
|
||||
var day : Int = 0
|
||||
class Power {
|
||||
var power_count: Int = 0
|
||||
var this_power_count: Int = 0
|
||||
var count_str: String = ""
|
||||
var list = ArrayList<PowerItem>()
|
||||
|
||||
class PowerItem {
|
||||
var id: Int = 0
|
||||
var name: String = ""
|
||||
var content: String = ""
|
||||
var image: String = ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* {
|
||||
"name": "骑士",
|
||||
"image": "https://cos.xscmmidi.site/admin/ScreenShot_2025-11-05_175044_144_17623369241246.png",
|
||||
"pay_price": "388.00",
|
||||
"power": {
|
||||
"power_count": 12,
|
||||
"this_power_count": 1,
|
||||
"count_str": "12/1",
|
||||
"list": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "专属徽章",
|
||||
"content": "专属动态爵位徽章",
|
||||
"image": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
*com.xscm.moduleutil.bean
|
||||
*qx
|
||||
*2025/11/10
|
||||
*
|
||||
*/
|
||||
class NobilityPrice {
|
||||
var lid : Int = 0
|
||||
var nobility_name : String = ""
|
||||
var nobility_image : String = ""
|
||||
var price : String = ""
|
||||
var pay_price : String = ""
|
||||
var day : Int = 0
|
||||
var end_time : String = ""
|
||||
var power_list = ArrayList<PowerItem>()
|
||||
|
||||
class PowerItem {
|
||||
var id : Int = 0
|
||||
var content : String = ""
|
||||
}
|
||||
|
||||
/* "lid": 2,
|
||||
"nobility_name": "男爵",
|
||||
"nobility_image": "https://cos.xscmmidi.site/admin/ScreenShot_2025-11-05_175121_076_17623369074684.png",
|
||||
"price": "588.00", //实付价格
|
||||
"pay_price": "588.00", //画线价格
|
||||
"day": 30,
|
||||
"power_list": [
|
||||
{
|
||||
"id": 1,
|
||||
"content": "专属动态爵位徽章"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"content": "设置昵称颜色字体"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"content": "特殊入场动画音效"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"content": "入场专属座驾动画"
|
||||
}
|
||||
],
|
||||
"end_time": "2025-12-10 10:19:20"*/
|
||||
}
|
||||
@@ -33,6 +33,7 @@ public class RoonGiftModel {
|
||||
private int num;//礼物数量
|
||||
private int activities_id;//4:盲盒 ;5:天空之境;
|
||||
private int gift_bag;//10:天空之境 11:岁月之城 12:时空之巅
|
||||
private int is_lock;//爵位礼物 0:不锁 1:锁
|
||||
public boolean isCan_send_self() {
|
||||
if ( isManghe()) {
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
*com.xscm.moduleutil.bean
|
||||
*qx
|
||||
*2025/11/8
|
||||
*
|
||||
*/
|
||||
class TableCellData {
|
||||
var title: String = ""
|
||||
var color: String = ""
|
||||
}
|
||||
@@ -1,23 +1,19 @@
|
||||
package com.xscm.moduleutil.bean;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.xscm.moduleutil.BaseEvent;
|
||||
import com.xscm.moduleutil.bean.room.FriendInfo;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
*@author qx
|
||||
*@data 2025/6/3
|
||||
*@description: 个人信息,点击我的获取
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class UserInfo extends BaseEvent implements Serializable {
|
||||
public class UserInfo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
public static final String FEMALE = "2";
|
||||
public static final String MALE = "1";
|
||||
@@ -72,9 +68,18 @@ public class UserInfo extends BaseEvent implements Serializable {
|
||||
private String red_num;
|
||||
private String ta;
|
||||
|
||||
private String nobility_image;//贵族图标
|
||||
private String nickname_color;//昵称颜色
|
||||
private String mic_cycle;//麦圈
|
||||
private String is_hide;//0不能设置,1:可以设置
|
||||
private String hide_status;//0-取消隐身,1-设置隐身
|
||||
|
||||
private String enter_image;//爵位飘屏的背景
|
||||
private String enter_text;//爵位飘屏的文字
|
||||
|
||||
|
||||
// @Data
|
||||
|
||||
// @Data
|
||||
// public static class TagList{
|
||||
// private String id;
|
||||
// private String tag_name;
|
||||
|
||||
@@ -6,6 +6,7 @@ data class EmotionDeatils(
|
||||
var type_id: Int? = 0,
|
||||
var name: String? = "",
|
||||
var image: String? = "",
|
||||
var is_lock: Int = 0,//0:未锁定 1:锁定
|
||||
var animate_image : String? = "",
|
||||
var children: List<Children>? =ArrayList (),
|
||||
)
|
||||
@@ -17,4 +18,5 @@ data class Children(
|
||||
var name: String? = "",
|
||||
var image: String? = "",
|
||||
var animate_image : String? = "",
|
||||
var is_lock: Int? = 0,//0:未锁定 1:锁定
|
||||
)
|
||||
@@ -37,6 +37,9 @@ public class RoomAuction implements Serializable {
|
||||
private String base_image;//礼物图片
|
||||
private long duration;//时间
|
||||
private String charm;
|
||||
private String nobility_image;//贵族图标
|
||||
private String nickname_color;//昵称颜色
|
||||
private String mic_cycle;//麦圈
|
||||
}
|
||||
|
||||
@Data
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.xscm.moduleutil.bean.MusicSongBean;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import com.xscm.moduleutil.bean.NobilitDeatils;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@@ -31,6 +32,7 @@ public class RoomInfoResp implements Serializable {
|
||||
private FriendInfo friend_info;
|
||||
private GiftXlh gift_cycle;
|
||||
private int hour_ranking_open;//1:开启 0:关闭
|
||||
private NobilitDeatils.NobilityInfo nobility_info;
|
||||
|
||||
|
||||
//弹出麦位操作弹出
|
||||
|
||||
@@ -29,7 +29,7 @@ public class RoomPitBean implements Serializable {
|
||||
*/
|
||||
|
||||
private String id;//id
|
||||
private String pit_number = "-1";//麦位号
|
||||
private String pit_number;//麦位号
|
||||
private String state;//麦位状态 正常 ,1封麦;3禁麦
|
||||
private int is_lock;//0未锁麦 1锁麦
|
||||
private int is_mute;//0未禁麦 1禁麦
|
||||
@@ -51,7 +51,7 @@ public class RoomPitBean implements Serializable {
|
||||
private String emchat_username;
|
||||
private String rank_id;
|
||||
private String nobility;
|
||||
// private String xin_dong;
|
||||
// private String xin_dong;
|
||||
private String banned;
|
||||
private String dress_picture;
|
||||
private RankInfo rank_info;
|
||||
@@ -65,4 +65,8 @@ public class RoomPitBean implements Serializable {
|
||||
private int heartId; // "heartId": 4,
|
||||
private int heartNum; // "heartNum": 10510
|
||||
|
||||
private String nobility_image;//贵族图标
|
||||
private String nickname_color;//昵称颜色
|
||||
private String mic_cycle;//麦圈
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,10 @@ public class RoomUserBean implements Serializable {
|
||||
private String is_mute;//是否在本房间禁言 1是 0否
|
||||
private String is_mute_pit;//是否在本房间内禁麦 1是 0否
|
||||
|
||||
private String nobility_image;//贵族图标
|
||||
private String nickname_color;//昵称颜色
|
||||
private String mic_cycle;//麦圈
|
||||
|
||||
// private int banned;
|
||||
// private int favorite;
|
||||
// private int pit;
|
||||
|
||||
@@ -288,12 +288,11 @@ public interface ApiServer {
|
||||
@GET(Constants.GET_GIFT_LABEL)
|
||||
Call<BaseModel<List<GiftLabelBean>>> getGiftLabel(@Query("have_hot") String have_hot);
|
||||
|
||||
//获取礼物列表
|
||||
@GET(Constants.GIFT_LIST)
|
||||
//获取礼物列表
|
||||
Call<BaseModel<List<RoonGiftModel>>> getGiftList(@Query("label") int label,@Query("room_id")String room_id);
|
||||
|
||||
@GET(Constants.TOPIC_LIST)
|
||||
//获取话题
|
||||
@GET(Constants.TOPIC_LIST)//获取话题
|
||||
Call<BaseModel<List<HeatedBean>>> topicList(@Query("page") String page, @Query("page_limit") String page_limit);
|
||||
|
||||
@FormUrlEncoded
|
||||
@@ -357,6 +356,10 @@ public interface ApiServer {
|
||||
@POST(Constants.CANCEL)
|
||||
Call<BaseModel<String>> cancel(@Field("token") String token);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_MODIFY_HIDE_STATUS)
|
||||
Call<BaseModel<String>> getModifyHideStatus(@Field("hide_status") String hide_status);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.DELETE_ZONE)
|
||||
Call<BaseModel<String>> deleteZone(@Field("id") String id);
|
||||
@@ -512,7 +515,8 @@ public interface ApiServer {
|
||||
@Field("coin") String coin,
|
||||
@Field("type") String type,
|
||||
@Field("type_params") String type_params,
|
||||
@Field("type_id") String type_id
|
||||
@Field("type_id") String type_id,
|
||||
@Field("nobility_id") String nobility_id
|
||||
);
|
||||
|
||||
@FormUrlEncoded
|
||||
@@ -753,6 +757,15 @@ public interface ApiServer {
|
||||
@POST(Constants.GIFT_SEND)
|
||||
Call<BaseModel<String>> giftSend(@Field("send_id")String send_id);
|
||||
|
||||
@GET(Constants.GET_NOBILITY_DETAIL)
|
||||
Call<BaseModel<NobilitDeatils>> getNobilityDetail();
|
||||
|
||||
@GET(Constants.GET_NOBILITY_LIST)
|
||||
Call<BaseModel<List<NobilitList>>> getNobilityList();
|
||||
|
||||
@GET(Constants.GET_NOBILITY_PRICE)
|
||||
Call<BaseModel<NobilityPrice>> getNobilityPrice(@Query("id") String id);
|
||||
|
||||
@GET(Constants.GET_BOX_GIFT_LIST_XLH)
|
||||
Call<BaseModel<BlindBoxBean>> getBoxGiftListXLH( @Query("room_id") String room_id);
|
||||
|
||||
|
||||
@@ -788,7 +788,19 @@ public class RetrofitClient {
|
||||
@Override
|
||||
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
|
||||
if (response.code() == 200) {
|
||||
observer.onNext("任务完成");
|
||||
try {
|
||||
String json = response.body().string();
|
||||
BaseModel<String> baseModel = GsonUtils.fromJson(json, BaseModel.class);
|
||||
if (baseModel.getCode() == 1) {
|
||||
baseModel.setData(baseModel.getMsg());
|
||||
observer.onNext(baseModel.getData());
|
||||
} else {
|
||||
com.hjq.toast.ToastUtils.show(baseModel.getMsg());
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1408,8 +1420,8 @@ public class RetrofitClient {
|
||||
});
|
||||
}
|
||||
|
||||
public void getBanners(BaseObserver<List<BannerModel>> observer) {
|
||||
sApiServer.getBanners("3").enqueue(new Callback<BaseModel<List<BannerModel>>>() {
|
||||
public void getBanners(String s,BaseObserver<List<BannerModel>> observer) {
|
||||
sApiServer.getBanners(s).enqueue(new Callback<BaseModel<List<BannerModel>>>() {
|
||||
@Override
|
||||
public void onResponse(Call<BaseModel<List<BannerModel>>> call, Response<BaseModel<List<BannerModel>>> response) {
|
||||
if (response.code() == 200) {
|
||||
@@ -2132,8 +2144,8 @@ public class RetrofitClient {
|
||||
// });
|
||||
}
|
||||
|
||||
public void appPay(String user_id, String money, String coin, String type, String type_params, String type_id, BaseObserver<AppPay> observer) {
|
||||
sApiServer.appPay(user_id, money, coin, type, type_params, type_id).enqueue(new Callback<BaseModel<AppPay>>() {
|
||||
public void appPay(String user_id, String money, String coin, String type, String type_params, String type_id,String nobility_id, BaseObserver<AppPay> observer) {
|
||||
sApiServer.appPay(user_id, money, coin, type, type_params, type_id,nobility_id).enqueue(new Callback<BaseModel<AppPay>>() {
|
||||
@Override
|
||||
public void onResponse(Call<BaseModel<AppPay>> call, Response<BaseModel<AppPay>> response) {
|
||||
if (response.code() == 200) {
|
||||
@@ -3389,7 +3401,19 @@ public class RetrofitClient {
|
||||
}
|
||||
});
|
||||
}
|
||||
public void getModifyHideStatus(String hide_status, BaseObserver<String> observer ){
|
||||
sApiServer.getModifyHideStatus(hide_status).enqueue(new Callback<BaseModel<String>>() {
|
||||
@Override
|
||||
public void onResponse(Call<BaseModel<String>> call, Response<BaseModel<String>> response) {
|
||||
onNextRetu(response, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<BaseModel<String>> call, Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
public void getPostData(String new_password, String mobile, String code, String userId, BaseObserver<String> observer) {
|
||||
sApiServer.getPostData(new_password, mobile, code, userId).enqueue(new Callback<BaseModel<String>>() {
|
||||
@Override
|
||||
@@ -3943,6 +3967,87 @@ public class RetrofitClient {
|
||||
});
|
||||
}
|
||||
|
||||
public void getNobilityDetail(BaseObserver<NobilitDeatils> observer){
|
||||
sApiServer.getNobilityDetail().enqueue(new Callback<BaseModel<NobilitDeatils>>() {
|
||||
@Override
|
||||
public void onResponse(Call<BaseModel<NobilitDeatils>> call, Response<BaseModel<NobilitDeatils>> response) {
|
||||
if (response.code() == 200) {
|
||||
BaseModel<NobilitDeatils> baseModel = response.body();
|
||||
if (baseModel.getCode() == 1) {
|
||||
observer.onNext(baseModel.getData());
|
||||
}else if (baseModel.getCode() == 0){
|
||||
ToastUtils.showShort(baseModel.getMsg());
|
||||
}else if (baseModel.getCode() == 301){
|
||||
try {
|
||||
ToastUtils.showShort(baseModel.getMsg());
|
||||
CommonAppContext.getInstance().clearLoginInfo();
|
||||
} catch (ClassNotFoundException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(Call<BaseModel<NobilitDeatils>> call, Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void getNobilityList(BaseObserver<List<NobilitList>> observer){
|
||||
sApiServer.getNobilityList().enqueue(new Callback<BaseModel<List<NobilitList>>>() {
|
||||
@Override
|
||||
public void onResponse(Call<BaseModel<List<NobilitList>>> call, Response<BaseModel<List<NobilitList>>> response) {
|
||||
if (response.code() == 200) {
|
||||
BaseModel<List<NobilitList>> baseModel = response.body();
|
||||
if (baseModel.getCode() == 1) {
|
||||
observer.onNext(baseModel.getData());
|
||||
}else if (baseModel.getCode() == 0){
|
||||
ToastUtils.showShort(baseModel.getMsg());
|
||||
}else if (baseModel.getCode() == 301){
|
||||
try {
|
||||
ToastUtils.showShort(baseModel.getMsg());
|
||||
CommonAppContext.getInstance().clearLoginInfo();
|
||||
} catch (ClassNotFoundException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<BaseModel<List<NobilitList>>> call, Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void getNobilityPrice(String id, BaseObserver<NobilityPrice> observer){
|
||||
sApiServer.getNobilityPrice(id).enqueue(new Callback<BaseModel<NobilityPrice>>() {
|
||||
@Override
|
||||
public void onResponse(Call<BaseModel<NobilityPrice>> call, Response<BaseModel<NobilityPrice>> response) {
|
||||
if (response.code() == 200) {
|
||||
BaseModel<NobilityPrice> baseModel = response.body();
|
||||
if (baseModel.getCode() == 1) {
|
||||
observer.onNext(baseModel.getData());
|
||||
}else if (baseModel.getCode() == 0){
|
||||
ToastUtils.showShort(baseModel.getMsg());
|
||||
}else if (baseModel.getCode() == 301){
|
||||
try {
|
||||
ToastUtils.showShort(baseModel.getMsg());
|
||||
CommonAppContext.getInstance().clearLoginInfo();
|
||||
} catch (ClassNotFoundException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<BaseModel<NobilityPrice>> call, Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void giftSend(String send_id, BaseObserver<String> observer) {
|
||||
sApiServer.giftSend(send_id).enqueue(new Callback<BaseModel<String>>() {
|
||||
@Override
|
||||
|
||||
@@ -48,7 +48,7 @@ public class RechargeDialogPresenter extends BasePresenter<RechargeDialogContact
|
||||
|
||||
@Override
|
||||
public void appPay(String user_id, String money, String coin, String type, String type_params, String type_id) {
|
||||
api.appPay(user_id, money, coin, type,type_params,type_id, new BaseObserver<AppPay>() {
|
||||
api.appPay(user_id, money, coin, type,type_params,type_id,"", new BaseObserver<AppPay>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
addDisposable(d);
|
||||
|
||||
@@ -9,6 +9,7 @@ import static io.agora.rtc2.video.VideoEncoderConfiguration.ORIENTATION_MODE.*;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.hardware.SensorManager;
|
||||
@@ -57,6 +58,9 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.agora.mediaplayer.IMediaPlayerObserver;
|
||||
import io.agora.mediaplayer.data.CacheStatistics;
|
||||
@@ -83,9 +87,9 @@ import io.agora.rtc2.video.VideoEncoderConfiguration;
|
||||
public class AgoraManager {
|
||||
|
||||
private static volatile AgoraManager instance;
|
||||
public static RtcEngineEx rtcEngine;
|
||||
public RtcEngineEx rtcEngine;
|
||||
// private RtcEngineEx rtcEngineEx;
|
||||
private static Context context;
|
||||
private Context context;
|
||||
private boolean isLocalAudioEnabled = true; // 默认开启麦克风
|
||||
// private final List<IRtcEngineEventHandler> eventHandlers = new ArrayList<>();
|
||||
private static IAgoraMusicContentCenter musicContentCenter;
|
||||
@@ -102,16 +106,14 @@ public class AgoraManager {
|
||||
private String pkRoomId = "";
|
||||
private static String lastRoomId;
|
||||
|
||||
// 用于跟踪所有Handler,便于清理
|
||||
private static List<Handler> handlers = new ArrayList<>();
|
||||
|
||||
// 后台任务线程池,用于并行处理音乐相关任务
|
||||
private static ExecutorService executorService = Executors.newFixedThreadPool(3);
|
||||
|
||||
public int pkUserId;
|
||||
|
||||
public int getPkUserId() {
|
||||
return pkUserId;
|
||||
}
|
||||
|
||||
public void setPkUserId(int pkUserId) {
|
||||
this.pkUserId = pkUserId;
|
||||
}
|
||||
|
||||
public void setLastRoomId(String value) {
|
||||
lastRoomId = value;
|
||||
}
|
||||
@@ -122,27 +124,22 @@ public class AgoraManager {
|
||||
}
|
||||
|
||||
private AgoraManager() {
|
||||
// this.context = context.getApplicationContext();
|
||||
// init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId());
|
||||
|
||||
}
|
||||
|
||||
public static AgoraManager getInstance(Context con) {
|
||||
public static AgoraManager getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (AgoraManager.class) {
|
||||
if (instance == null) {
|
||||
instance = new AgoraManager();
|
||||
context = con.getApplicationContext(); // 使用ApplicationContext避免内存泄漏
|
||||
// init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId());
|
||||
// init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId());
|
||||
instance.context = CommonAppContext.getInstance(); // 使用ApplicationContext避免内存泄漏
|
||||
}
|
||||
}
|
||||
}
|
||||
// 确保引擎已初始化
|
||||
if (rtcEngine == null) {
|
||||
if (instance.rtcEngine == null) {
|
||||
synchronized (AgoraManager.class) {
|
||||
if (rtcEngine == null) {
|
||||
init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId());
|
||||
if (instance.rtcEngine == null) {
|
||||
instance.init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,11 +165,10 @@ public class AgoraManager {
|
||||
/**
|
||||
* 初始化 Agora 引擎
|
||||
*/
|
||||
public static void init(String appId) {
|
||||
public void init(String appId) {
|
||||
if (rtcEngine != null) {
|
||||
return;
|
||||
}
|
||||
;
|
||||
|
||||
synchronized (AgoraManager.class) {
|
||||
if (rtcEngine != null) {
|
||||
@@ -282,6 +278,8 @@ public class AgoraManager {
|
||||
*/
|
||||
public void cleanup() {
|
||||
try {
|
||||
// 清理所有Handler,防止内存泄漏
|
||||
clearAllHandlers();
|
||||
|
||||
if (rtcEngine != null) {
|
||||
// // 离开频道
|
||||
@@ -316,6 +314,54 @@ public class AgoraManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理所有Handler,防止内存泄漏
|
||||
*/
|
||||
private void clearAllHandlers() {
|
||||
synchronized (handlers) {
|
||||
for (Handler handler : handlers) {
|
||||
if (handler != null) {
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
}
|
||||
handlers.clear();
|
||||
}
|
||||
|
||||
// 关闭线程池
|
||||
if (executorService != null && !executorService.isShutdown()) {
|
||||
executorService.shutdown();
|
||||
try {
|
||||
if (!executorService.awaitTermination(1, TimeUnit.SECONDS)) {
|
||||
executorService.shutdownNow();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
executorService.shutdownNow();
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
executorService = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并跟踪Handler
|
||||
*/
|
||||
private Handler createTrackedHandler(Looper looper) {
|
||||
Handler handler = new Handler(looper);
|
||||
synchronized (handlers) {
|
||||
handlers.add(handler);
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在后台线程池中执行任务
|
||||
*/
|
||||
private void executeInBackground(Runnable task) {
|
||||
if (executorService != null && !executorService.isShutdown()) {
|
||||
executorService.execute(task);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isOnJoin = false;
|
||||
|
||||
public boolean isOnJoin() {
|
||||
@@ -329,7 +375,7 @@ public class AgoraManager {
|
||||
/**
|
||||
* 默认事件处理器,转发给所有监听器
|
||||
*/
|
||||
private static IRtcEngineEventHandler getDefaultEventHandler() {
|
||||
private IRtcEngineEventHandler getDefaultEventHandler() {
|
||||
return new IRtcEngineEventHandler() {
|
||||
|
||||
@Override
|
||||
@@ -362,46 +408,6 @@ public class AgoraManager {
|
||||
// 填入用于鉴权的 Token
|
||||
contentCenterConfiguration.token = SpUtil.getRtmToken();
|
||||
|
||||
// 创建 IAgoraMusicContentCenterEventHandler,用于 SDK 向客户端发送音乐内容中心事件通知
|
||||
// contentCenterConfiguration.eventHandler = new IMusicContentCenterEventHandler() {
|
||||
// @Override
|
||||
// public void onPreLoadEvent(String requestId, long songCode, int percent, String lyricUrl, int status, int errorCode) {
|
||||
// LogUtils.e("@@@1", "requestId: " + requestId + ", songCode: " + songCode + ", percent: " + percent + ", lyricUrl: " + lyricUrl + ", status: " + status + ", errorCode: " + errorCode);
|
||||
// if (!lyricUrl.isEmpty() && percent == 100 && !isBjMusic) {
|
||||
// getLyricsInstance(lyricUrl);
|
||||
// }
|
||||
//// musicPlayer.open(songCode, 0);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onMusicCollectionResult(String requestId, int page, int pageSize, int total, Music[] list, int errorCode) {
|
||||
// LogUtils.e("@@@2", "requestId: " + requestId + ", page: " + page + ", pageSize: " + pageSize + ", total: " + total);
|
||||
// MusicBean musicBean = new MusicBean();
|
||||
// musicBean.setMusicList(Arrays.asList(list));
|
||||
// musicBean.setPage(page);
|
||||
// EventBus.getDefault().post(musicBean);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onMusicChartsResult(String requestId, MusicChartInfo[] list, int errorCode) {
|
||||
// LogUtils.e("@@@", "requestId: " + requestId);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onLyricResult(String requestId, long songCode, String lyricUrl, int errorCode) {
|
||||
// LogUtils.e("@@@22", "requestId: " + requestId + ", songCode: " + songCode + ", lyricUrl: " + lyricUrl + ", errorCode: " + errorCode);
|
||||
// if (lyricUrl != null && !isBjMusic) {
|
||||
// getLyricsInstance(lyricUrl);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onSongSimpleInfoResult(String requestId, long songCode, String simpleInfo, int errorCode) {
|
||||
// LogUtils.e("@@@", "requestId: " + requestId + ", songCode: " + songCode + ", simpleInfo: " + simpleInfo + ", errorCode: " + errorCode);
|
||||
// }
|
||||
// };
|
||||
// 初始化 IAgoraMusicContentCenter
|
||||
|
||||
musicContentCenter.initialize(contentCenterConfiguration);
|
||||
if (musicPlayer != null) {
|
||||
musicPlayer = null;
|
||||
@@ -473,12 +479,6 @@ public class AgoraManager {
|
||||
|
||||
@Override
|
||||
public void onUserJoined(int uid, int elapsed) {//远端用户加入频道
|
||||
// for (IRtcEngineEventHandler handler : eventHandlers) {
|
||||
// if (handler != null) {
|
||||
// handler.onUserJoined(uid, elapsed);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) {
|
||||
if (listener != null) {
|
||||
@@ -500,19 +500,13 @@ public class AgoraManager {
|
||||
|
||||
@Override
|
||||
public void onUserOffline(int uid, int reason) {//远端用户离开频道
|
||||
// for (IRtcEngineEventHandler handler : eventHandlers) {
|
||||
// if (handler != null) {
|
||||
// handler.onUserOffline(uid, reason);
|
||||
// }
|
||||
for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) {
|
||||
if (listener != null) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
// 远程用户音量变化
|
||||
listener.userOffline(uid, reason);
|
||||
// }
|
||||
});
|
||||
}
|
||||
// }
|
||||
}
|
||||
SurfaceView renderView = null;
|
||||
rtcEngine.setupRemoteVideo(new VideoCanvas(null, Constants.RENDER_MODE_FIT, uid));
|
||||
@@ -535,7 +529,6 @@ public class AgoraManager {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
// 远程用户音量变化
|
||||
listener.onRemoteSoundLevelUpdate(uid > 0 ? String.valueOf(uid) : SpUtil.getUserId() + "", volume);
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -597,7 +590,7 @@ public class AgoraManager {
|
||||
/**
|
||||
* 创建并返回 IMediaPlayerObserver 实例
|
||||
*/
|
||||
private static IMediaPlayerObserver createMediaPlayerObserver() {
|
||||
private IMediaPlayerObserver createMediaPlayerObserver() {
|
||||
return new IMediaPlayerObserver() {
|
||||
@Override
|
||||
public void onPlayerStateChanged(io.agora.mediaplayer.Constants.MediaPlayerState state, io.agora.mediaplayer.Constants.MediaPlayerReason reason) {
|
||||
@@ -720,10 +713,6 @@ public class AgoraManager {
|
||||
connection.localUid = SpUtil.getUserId();
|
||||
pkRoomId = channelId;
|
||||
pkUserId = Integer.parseInt(pkUserIds);
|
||||
// rtcEngine.joinChannelEx(token, connection, options, getDefaultEventHandler());
|
||||
// muteAllRemoteAudioStreamsEx(true);
|
||||
// muteAllRemoteAudioStreamsExUserId(false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -732,24 +721,12 @@ public class AgoraManager {
|
||||
RtcConnection connection = new RtcConnection();
|
||||
connection.channelId = mRoomId;
|
||||
connection.localUid = uid;
|
||||
// rtcEngine.leaveChannelEx(connection);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateChannelMediaOptions() {
|
||||
|
||||
if (rtcEngine != null) {
|
||||
options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER;
|
||||
// options.autoSubscribeVideo = true;
|
||||
// options.autoSubscribeAudio = true;
|
||||
//// 不发布摄像头采集的视频
|
||||
// options.publishCameraTrack = false;
|
||||
//// 不发布麦克风采集的视频
|
||||
// options.publishMicrophoneTrack = false;
|
||||
//// 在频道中发布屏幕采集的视频
|
||||
// options.publishScreenCaptureVideo = true;
|
||||
//// 在频道中发布屏幕采集的音频
|
||||
// options.publishScreenCaptureAudio = true;
|
||||
rtcEngine.setScreenCaptureScenario(Constants.ScreenScenarioType.SCREEN_SCENARIO_VIDEO);
|
||||
rtcEngine.updateChannelMediaOptions(options);
|
||||
}
|
||||
@@ -757,30 +734,7 @@ public class AgoraManager {
|
||||
|
||||
public void post() {
|
||||
if (rtcEngine != null) {
|
||||
// rtcEngine.setParameters("{\"che.video.mobile_1080p\":true}");
|
||||
// rtcEngine.setClientRole(Constants.CLIENT_ROLE_BROADCASTER);
|
||||
//
|
||||
// /*Enable video module*/
|
||||
// rtcEngine.enableVideo();
|
||||
// // Setup video encoding configs
|
||||
// rtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
|
||||
// VD_640x360,
|
||||
// FRAME_RATE_FPS_15,
|
||||
// STANDARD_BITRATE,
|
||||
// ORIENTATION_MODE_ADAPTIVE
|
||||
// ));
|
||||
// /*Set up to play remote sound with receiver*/
|
||||
// rtcEngine.setDefaultAudioRoutetoSpeakerphone(true);
|
||||
|
||||
ScreenCaptureParameters screenCaptureParameters = new ScreenCaptureParameters();
|
||||
// screenCaptureParameters.captureVideo = true;
|
||||
// screenCaptureParameters.videoCaptureParameters.width = 1440;
|
||||
// screenCaptureParameters.videoCaptureParameters.height = 1940;
|
||||
// screenCaptureParameters.videoCaptureParameters.framerate = 15;
|
||||
// screenCaptureParameters.captureAudio = true;
|
||||
// screenCaptureParameters.audioCaptureParameters.captureSignalVolume = 50;
|
||||
//// screenCaptureParameters.videoCaptureParameters.bitrate = 500;
|
||||
// rtcEngine.startScreenCapture(screenCaptureParameters);
|
||||
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
Display display = manager.getDefaultDisplay();
|
||||
|
||||
@@ -1059,31 +1013,38 @@ public class AgoraManager {
|
||||
if (type == 1) {
|
||||
if (code < 0) {
|
||||
String result = musicContentCenter.preload(mSongCode);
|
||||
// 创建定时器,3秒后再次检查
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
// 使用后台线程池处理预加载检查,避免阻塞UI线程
|
||||
executeInBackground(() -> {
|
||||
try {
|
||||
Thread.sleep(3000); // 3秒延迟
|
||||
Log.d("AgoraManager", "Preload result: " + result);
|
||||
// 切换回主线程执行后续操作
|
||||
createTrackedHandler(Looper.getMainLooper()).post(() -> {
|
||||
isPreload(mSongCode, type);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.e("AgoraManager", "Preload song failed: songCode=" + mSongCode, e);
|
||||
}
|
||||
}, 3000); // 3秒延迟
|
||||
});
|
||||
} else {
|
||||
handleMusicPlayerState(songCode);
|
||||
}
|
||||
} else if (type == 2) {
|
||||
if (code < 0) {
|
||||
String result = musicContentCenter.preload(mSongCode);
|
||||
// 创建定时器,3秒后再次检查
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
// 使用后台线程池处理预加载检查,避免阻塞UI线程
|
||||
executeInBackground(() -> {
|
||||
try {
|
||||
|
||||
Thread.sleep(3000); // 3秒延迟
|
||||
Log.d("AgoraManager", "Preload result: " + result);
|
||||
// 切换回主线程执行后续操作
|
||||
createTrackedHandler(Looper.getMainLooper()).post(() -> {
|
||||
isPreload(mSongCode, type);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.e("AgoraManager", "Preload song failed: songCode=" + mSongCode, e);
|
||||
}
|
||||
}, 3000); // 3秒延迟
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
musicPlayer.open(mSongCode, 0);
|
||||
@@ -1111,9 +1072,18 @@ public class AgoraManager {
|
||||
case PLAYER_STATE_IDLE:
|
||||
LogUtils.e("lxj", "空闲");
|
||||
musicPlayer.open(songCode, 0);
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
// 使用后台线程处理延迟任务,避免阻塞UI线程
|
||||
executeInBackground(() -> {
|
||||
try {
|
||||
Thread.sleep(2000); // 2秒延迟
|
||||
// 切换回主线程执行后续操作
|
||||
createTrackedHandler(Looper.getMainLooper()).post(() -> {
|
||||
isPreload(songCode, 1);
|
||||
}, 2000); // 2秒延迟
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.e("AgoraManager", "Error in idle state handling", e);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case PLAYER_STATE_OPEN_COMPLETED:
|
||||
LogUtils.e("lxj", "播放");
|
||||
@@ -1151,143 +1121,7 @@ public class AgoraManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static void isPreload2(long songCode, int type) {
|
||||
mSongCode = songCode;
|
||||
|
||||
// 确保 rtcEngine 已初始化
|
||||
if (rtcEngine == null) {
|
||||
Log.e("AgoraManager", "RtcEngine not initialized, cannot preload music");
|
||||
return;
|
||||
}
|
||||
|
||||
// 初始化 musicContentCenter 如果为 null
|
||||
if (musicContentCenter == null) {
|
||||
try {
|
||||
musicContentCenter = IAgoraMusicContentCenter.create(rtcEngine);
|
||||
if (musicContentCenter == null) {
|
||||
Log.e("AgoraManager", "Failed to create musicContentCenter");
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("AgoraManager", "Exception creating musicContentCenter", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化 musicPlayer 如果为 null
|
||||
if (musicPlayer == null) {
|
||||
try {
|
||||
musicPlayer = musicContentCenter.createMusicPlayer();
|
||||
if (musicPlayer == null) {
|
||||
Log.e("AgoraManager", "Failed to create musicPlayer");
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("AgoraManager", "Exception creating musicPlayer", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int code;
|
||||
try {
|
||||
code = musicContentCenter.isPreloaded(mSongCode);
|
||||
} catch (Exception e) {
|
||||
Log.e("AgoraManager", "Exception checking if song is preloaded", e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == 1) {
|
||||
if (code < 0) {
|
||||
// 创建定时器,3秒后再次检查
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
try {
|
||||
String result = musicContentCenter.preload(mSongCode);
|
||||
Log.d("AgoraManager", "Preload result: " + result);
|
||||
isPreload2(mSongCode, type);
|
||||
} catch (Exception e) {
|
||||
Log.e("AgoraManager", "Preload song failed: songCode=" + mSongCode, e);
|
||||
}
|
||||
}, 3000); // 3秒延迟
|
||||
} else {
|
||||
handleMusicPlayerState2(songCode);
|
||||
}
|
||||
} else if (type == 2) {
|
||||
if (code < 0) {
|
||||
// 创建定时器,3秒后再次检查
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
try {
|
||||
String result = musicContentCenter.preload(mSongCode);
|
||||
Log.d("AgoraManager", "Preload result: " + result);
|
||||
isPreload2(mSongCode, type);
|
||||
} catch (Exception e) {
|
||||
Log.e("AgoraManager", "Preload song failed: songCode=" + mSongCode, e);
|
||||
}
|
||||
}, 3000); // 3秒延迟
|
||||
} else {
|
||||
try {
|
||||
musicPlayer.open(mSongCode, 0);
|
||||
} catch (Exception e) {
|
||||
Log.e("AgoraManager", "Open music failed: songCode=" + mSongCode, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 提取音乐播放器状态处理逻辑到单独的方法
|
||||
private static void handleMusicPlayerState2(long songCode) {
|
||||
if (musicPlayer == null) {
|
||||
Log.e("AgoraManager", "Music player is null, cannot handle state");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
io.agora.mediaplayer.Constants.MediaPlayerState state = musicPlayer.getState();
|
||||
switch (state) {
|
||||
case PLAYER_STATE_PAUSED:
|
||||
LogUtils.e("lxj", "暂停");
|
||||
musicPlayer.resume();
|
||||
break;
|
||||
case PLAYER_STATE_IDLE:
|
||||
LogUtils.e("lxj", "空闲");
|
||||
musicPlayer.open(songCode, 0);
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
isPreload2(songCode, 1);
|
||||
}, 3000); // 3秒延迟
|
||||
break;
|
||||
case PLAYER_STATE_OPEN_COMPLETED:
|
||||
LogUtils.e("lxj", "播放");
|
||||
musicPlayer.play();
|
||||
// musicPlayer.selectAudioTrack(0);
|
||||
break;
|
||||
case PLAYER_STATE_PAUSING_INTERNAL:
|
||||
LogUtils.e("lxj", "关闭");
|
||||
musicPlayer.pause();
|
||||
break;
|
||||
case PLAYER_STATE_PLAYBACK_ALL_LOOPS_COMPLETED:
|
||||
LogUtils.e("lxj", "daki");
|
||||
musicPlayer.open(songCode, 0);
|
||||
isPreload2(songCode, 1);
|
||||
break;
|
||||
case PLAYER_STATE_OPENING:
|
||||
LogUtils.e("lxj", state.toString());
|
||||
// isPreload2(songCode, 1);
|
||||
break;
|
||||
case PLAYER_STATE_PLAYING:
|
||||
LogUtils.e("lxj", state.toString());
|
||||
isPreload2(songCode, 1);
|
||||
break;
|
||||
case PLAYER_STATE_STOPPED:
|
||||
LogUtils.e("lxj", state.toString());
|
||||
isPreload2(songCode, 1);
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("lxj", "未知状态: " + state);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("AgoraManager", "Exception handling music player state", e);
|
||||
}
|
||||
}
|
||||
// 删除重复的isPreload2方法,统一使用isPreload方法
|
||||
|
||||
|
||||
public void play() {
|
||||
@@ -1425,14 +1259,23 @@ public class AgoraManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static void nextSong() {
|
||||
public void nextSong() {
|
||||
if (musicList != null && musicList.size() > 0) {
|
||||
stopMuisc();
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
// 使用后台线程处理延迟任务,避免阻塞UI线程
|
||||
executeInBackground(() -> {
|
||||
try {
|
||||
Thread.sleep(3000); // 3秒延迟
|
||||
// 切换回主线程执行UI更新操作
|
||||
createTrackedHandler(Looper.getMainLooper()).post(() -> {
|
||||
EventBus.getDefault().post(musicList.get(0));
|
||||
isPreload2(musicList.get(0).songCode, 1);
|
||||
isPreload(musicList.get(0).songCode, 1);
|
||||
musicList.remove(musicList.get(0));
|
||||
}, 3000); // 3秒延迟
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.e("AgoraManager", "Error in nextSong", e);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
stopMuisc();
|
||||
@@ -1517,12 +1360,30 @@ public class AgoraManager {
|
||||
}
|
||||
|
||||
public static byte[] convertFileToByteArray(File file) {
|
||||
if (file == null || !file.exists()) {
|
||||
Log.e("AgoraManager", "File is null or does not exist");
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] byteArray = null;
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
byteArray = new byte[(int) file.length()];
|
||||
fis.read(byteArray);
|
||||
int bytesRead = fis.read(byteArray);
|
||||
if (bytesRead != byteArray.length) {
|
||||
Log.w("AgoraManager", "Could not read entire file: " + file.getPath());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e("AgoraManager", "Error converting file to byte array", e);
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (Exception e) {
|
||||
Log.e("AgoraManager", "Error closing file input stream", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
@@ -36,62 +36,35 @@ import io.agora.rtc2.video.VideoCanvas;
|
||||
public class AgoraManagerEx {
|
||||
|
||||
private static volatile AgoraManagerEx instance;
|
||||
private static RtcEngineEx rtcEngineEx;
|
||||
// private RtcEngineEx rtcEngineEx;
|
||||
private static Context context;
|
||||
private boolean isLocalAudioEnabled = true; // 默认开启麦克风
|
||||
// private final List<IRtcEngineEventHandler> eventHandlers = new ArrayList<>();
|
||||
private static IAgoraMusicContentCenter musicContentCenter;
|
||||
private static IAgoraMusicPlayer musicPlayer;
|
||||
private static MusicContentCenterConfiguration contentCenterConfiguration;
|
||||
private static String mRoomId = "";
|
||||
private static long mSongCode;
|
||||
|
||||
private static List<Music> musicList;
|
||||
private static boolean isBjMusic = false;
|
||||
private static List<SoundLevelUpdateListener> soundLevelUpdateListeners = new CopyOnWriteArrayList<>();
|
||||
private static ChannelMediaOptions options;
|
||||
private static RtcConnection connection;
|
||||
private RtcEngineEx rtcEngineEx;
|
||||
private Context context;
|
||||
private List<SoundLevelUpdateListener> soundLevelUpdateListeners = new CopyOnWriteArrayList<>();
|
||||
private ChannelMediaOptions options;
|
||||
private RtcConnection connection;
|
||||
private String pkRoomId = "";
|
||||
private static String lastRoomId;
|
||||
|
||||
public int pkUserId;
|
||||
|
||||
public int getPkUserId() {
|
||||
return pkUserId;
|
||||
}
|
||||
|
||||
public void setPkUserId(int pkUserId) {
|
||||
this.pkUserId = pkUserId;
|
||||
}
|
||||
private static boolean isOnJoin = false;
|
||||
public void setLastRoomId(String value) {
|
||||
lastRoomId = value;
|
||||
}
|
||||
|
||||
public String getLastRoomId() {
|
||||
LogUtils.e("上次的房间id:" + lastRoomId);
|
||||
return lastRoomId;
|
||||
}
|
||||
|
||||
private AgoraManagerEx() {
|
||||
|
||||
}
|
||||
|
||||
public static AgoraManagerEx getInstance(Context con) {
|
||||
public static AgoraManagerEx getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (AgoraManagerEx.class) {
|
||||
if (instance == null) {
|
||||
instance = new AgoraManagerEx();
|
||||
context = con.getApplicationContext(); // 使用ApplicationContext避免内存泄漏
|
||||
instance.context = CommonAppContext.getInstance(); // 使用ApplicationContext避免内存泄漏
|
||||
}
|
||||
}
|
||||
}
|
||||
// 确保引擎已初始化
|
||||
if (rtcEngineEx == null) {
|
||||
if (instance.rtcEngineEx == null) {
|
||||
synchronized (AgoraManagerEx.class) {
|
||||
if (rtcEngineEx == null) {
|
||||
init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId());
|
||||
if (instance.rtcEngineEx == null) {
|
||||
instance.init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -99,72 +72,20 @@ public class AgoraManagerEx {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void init(String appId) {
|
||||
if (rtcEngineEx != null) {
|
||||
return;
|
||||
};
|
||||
|
||||
synchronized (AgoraManager.class) {
|
||||
public void init(String appId) {
|
||||
if (rtcEngineEx != null) {
|
||||
return;
|
||||
}
|
||||
rtcEngineEx =AgoraManager.getInstance( context).rtcEngine;
|
||||
|
||||
// try {
|
||||
// RtcEngineConfig config = new RtcEngineConfig();
|
||||
// config.mContext = context;
|
||||
// config.mAppId = appId;
|
||||
// config.mEventHandler = getDefaultEventHandler();
|
||||
// config.mChannelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
|
||||
// config.mAudioScenario = Constants.AUDIO_SCENARIO_CHORUS;
|
||||
// config.mAreaCode = 1;
|
||||
//
|
||||
// rtcEngineEx = (RtcEngineEx) RtcEngineEx.create(config);
|
||||
// } catch (Exception e) {
|
||||
// Log.e("AgoraManager", "Failed to create RtcEngine", e);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (rtcEngineEx != null) {
|
||||
// try {
|
||||
// rtcEngineEx.setAudioProfile(Constants.AUDIO_PROFILE_MUSIC_HIGH_QUALITY_STEREO,
|
||||
// Constants.AUDIO_SCENARIO_GAME_STREAMING);
|
||||
// rtcEngineEx.enableAudioVolumeIndication(200, 3, true);
|
||||
// rtcEngineEx.setClientRole(Constants.CLIENT_ROLE_BROADCASTER);
|
||||
// rtcEngineEx.muteLocalAudioStream(true); // 默认静音
|
||||
// rtcEngineEx.muteAllRemoteAudioStreams(false); // 监听远端的音频
|
||||
//
|
||||
// // 设置参数时添加异常处理
|
||||
// try {
|
||||
// rtcEngineEx.setParameters("{\"che.audio.custom_payload_type\":73}");
|
||||
// rtcEngineEx.setParameters("{\"che.audio.custom_bitrate\":128000}");
|
||||
// rtcEngineEx.setParameters("{\"rtc.enable_nasa2\": true}");
|
||||
// rtcEngineEx.setParameters("{\"rtc.use_audio4\": true}");
|
||||
// rtcEngineEx.setParameters("{" +
|
||||
// "\"rtc.report_app_scenario\":" +
|
||||
// "{" +
|
||||
// "\"appScenario\":" + 100 + "," +
|
||||
// "\"serviceType\":" + 11 + "," +
|
||||
// "\"appVersion\":\"" + rtcEngineEx.getSdkVersion() + "\"" +
|
||||
// "}" +
|
||||
// "}");
|
||||
// rtcEngineEx.setParameters("{\"che.video.mobile_1080p\":true}");
|
||||
// } catch (Exception e) {
|
||||
// Log.w("AgoraManager", "Failed to set parameters", e);
|
||||
// }
|
||||
// /*Enable video module*/
|
||||
// rtcEngineEx.enableVideo();
|
||||
// /*Set up to play remote sound with receiver*/
|
||||
// rtcEngineEx.setDefaultAudioRoutetoSpeakerphone(true);
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// Log.e("AgoraManager", "Failed to configure rtcEngineEx", e);
|
||||
// }
|
||||
// }
|
||||
synchronized (AgoraManagerEx.class) {
|
||||
if (rtcEngineEx != null) {
|
||||
return;
|
||||
}
|
||||
rtcEngineEx = AgoraManager.getInstance().rtcEngine;
|
||||
}
|
||||
}
|
||||
|
||||
private static IRtcEngineEventHandler getDefaultEventHandler() {
|
||||
private IRtcEngineEventHandler getDefaultEventHandler() {
|
||||
return new IRtcEngineEventHandler() {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -53,7 +53,17 @@ public class ImageLoader {
|
||||
Glide.with(context).load(url).error(R.mipmap.default_image).placeholder(R.mipmap.default_image)
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL).into(view);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载图片并灰度
|
||||
* @param context
|
||||
* @param view
|
||||
* @param url
|
||||
* @param placeholder
|
||||
*/
|
||||
public static void loadImage(Context context,ImageView view, String url, Float placeholder) {
|
||||
Glide.with(context).load(url).apply(RequestOptions.bitmapTransform(new GrayscaleTransformation(placeholder)))
|
||||
.error(R.mipmap.default_image).placeholder(R.mipmap.default_image).diskCacheStrategy(DiskCacheStrategy.ALL).into(view);
|
||||
}
|
||||
// 可调节灰度程度的方法
|
||||
public static void loadGrayscaleImage(Context context, String url, ImageView imageView, float saturation) {
|
||||
Glide.with(context)
|
||||
|
||||
@@ -209,7 +209,8 @@ public class ImageUtils {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Glide.with(mImageView).load(path).error(R.mipmap.default_avatar).placeholder(R.mipmap.default_avatar).centerCrop().diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView);
|
||||
Glide.with(mImageView).load(path).error(R.mipmap.default_avatar).placeholder(R.mipmap.default_avatar).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView);
|
||||
|
||||
}
|
||||
|
||||
public static void loadHeadCC(String path, ImageView mImageView, LinearLayout.LayoutParams params) {
|
||||
|
||||
@@ -21,6 +21,7 @@ public class MeHeadView extends ConstraintLayout {
|
||||
private AvatarFrameView mIvFrame;
|
||||
private ImageView mIvSex;
|
||||
private ImageView mIvOnline;
|
||||
private ImageView iv_frame_bg;
|
||||
|
||||
public MeHeadView(Context context) {
|
||||
this(context, null, 0);
|
||||
@@ -41,10 +42,12 @@ public class MeHeadView extends ConstraintLayout {
|
||||
mIvFrame = findViewById(R.id.iv_frame);
|
||||
mIvSex = findViewById(R.id.iv_sex);
|
||||
mIvOnline = findViewById(R.id.iv_online);
|
||||
iv_frame_bg=findViewById(R.id.iv_frame_bg);
|
||||
mIvSex.setVisibility(GONE);
|
||||
}
|
||||
|
||||
public void setData(String headPicture, String framePicture, String sex) {
|
||||
Logger.e(headPicture, framePicture, sex);
|
||||
public void setData(String headPicture, String framePicture, String nobilityImage) {
|
||||
Logger.e(headPicture, framePicture, nobilityImage);
|
||||
if (!TextUtils.isEmpty(headPicture)) {
|
||||
ImageUtils.loadHeadCC(headPicture, mRiv);
|
||||
}
|
||||
@@ -55,19 +58,26 @@ public class MeHeadView extends ConstraintLayout {
|
||||
mIvFrame.setVisibility(VISIBLE);
|
||||
mIvFrame.setSource(framePicture, 1);
|
||||
}
|
||||
if (!TextUtils.isEmpty(sex)) {
|
||||
mIvSex.setVisibility(VISIBLE);
|
||||
if (sex.equals("1")){
|
||||
mIvSex.setBackgroundResource(R.mipmap.nan);
|
||||
}else {
|
||||
mIvSex.setBackgroundResource(R.mipmap.nv);
|
||||
}
|
||||
|
||||
} else {
|
||||
mIvSex.setVisibility(GONE);
|
||||
}
|
||||
// if (!TextUtils.isEmpty(sex)) {
|
||||
// mIvSex.setVisibility(GONE);
|
||||
// if (sex.equals("1")){
|
||||
// mIvSex.setBackgroundResource(R.mipmap.nan);
|
||||
// }else {
|
||||
// mIvSex.setBackgroundResource(R.mipmap.nv);
|
||||
// }
|
||||
//
|
||||
// } else {
|
||||
// mIvSex.setVisibility(GONE);
|
||||
// }
|
||||
// ImageUtils.loadImageView(framePicture, mIvFrame);
|
||||
|
||||
if (nobilityImage!=null && !TextUtils.isEmpty(nobilityImage)){
|
||||
iv_frame_bg.setVisibility(VISIBLE);
|
||||
ImageUtils.loadHeadCC(nobilityImage, iv_frame_bg);
|
||||
}else {
|
||||
iv_frame_bg.setVisibility(GONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setOnline(boolean isOnline) {
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.xscm.moduleutil.utils.config;
|
||||
public enum EnvironmentEnum {
|
||||
// "https://vespa.qxyushen.top/",
|
||||
PRODUCTION(//生产环境
|
||||
"http://1.13.101.98/",
|
||||
"https://1.13.101.98/",
|
||||
"KvNmqZc+VMzO4CfGMd5zmG6w6OFwpFO/19TwXUWfHDOBgmnl9DgIuE+kbrjNNnxqhtP3pH7bBrnSaSeFtunr72q6sgpLsfuswcUroMvz2slaTBcNzCaLi+GSnM3gB/GdO47mwLdk+iYBTvPUOCIuT608Z29z09w+vPeUDoMCHJBGXu6uh7Nj6PtV1dfGoUvByk1ZF0WYVjIqKDcb3tXY4jonFh3XAWhzMy8xKwN6F2nuK2IcdIwaSPsvuMZmhatP6f9kOE+vnfweyCHS3RxiG474WIoZGJM8omrl3/pOVqE=",
|
||||
"https://oss-cn-beijing.aliyuncs.com/",
|
||||
"LTAI5tKgrfcFQxH46ZwWYgFW",
|
||||
@@ -17,7 +17,7 @@ public enum EnvironmentEnum {
|
||||
"http://1.13.101.98/h5",
|
||||
0),
|
||||
TEST(//测试环境
|
||||
"https://test.vespa.xscmmidi.site/",
|
||||
"http://test.vespa.xscmmidi.site/",
|
||||
"6rdWuz058oq5OahdbFiGEybUcdahd12J83L34Uc7MrPIrxtFG+rXiwDvRcqNvjwbClbbmvMrmxKVkIysFByBsl0Qe9kqd2w8T/nhK5G6eXXlk2V9AjYCieIU+jRnjZBB+Cfechr6rCGJ2aeBARIsXcRPW7wm9WFK9euh5T+v6Pyte68yNaNdcYCll3+U4/uCEog7HygCnMIbAU+kqoPdmn2H+51YOHW+VsnsHd4w1+I3f8Tt0xLIXGM4GWnQueZ5GR46GTWiSYMy8dCIh9SPIMRyC91GosVcfGPMJSdcXqc=",
|
||||
"https://oss-cn-beijing.aliyuncs.com/",
|
||||
"LTAI5tKgrfcFQxH46ZwWYgFW",
|
||||
@@ -28,7 +28,7 @@ public enum EnvironmentEnum {
|
||||
1600096890,
|
||||
"02f7339ec98947deaeab173599891932",
|
||||
"tcp://1.13.181.248",
|
||||
"https://test.vespa.qxyushen.top/h5",
|
||||
"https://test.vespa.xscmmidi.site/h5",
|
||||
1);
|
||||
|
||||
private final String serverUrl;//服务器地址
|
||||
|
||||
@@ -14,6 +14,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
import com.opensource.svgaplayer.SVGADrawable;
|
||||
import com.opensource.svgaplayer.SVGAImageView;
|
||||
import com.opensource.svgaplayer.SVGAParser;
|
||||
import com.opensource.svgaplayer.SVGAVideoEntity;
|
||||
@@ -41,6 +42,10 @@ import com.xscm.moduleutil.utils.logger.Logger;
|
||||
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
public abstract class BaseWheatView extends ConstraintLayout implements IBaseWheat {
|
||||
public ImageView mRiv;
|
||||
@@ -78,9 +83,14 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
|
||||
private boolean showGiftAnim = true;//显示麦位动画
|
||||
private ImageView iv_tag_type;
|
||||
|
||||
// 当前音量监听器,用于防止重复添加
|
||||
private SoundLevelUpdateListener currentSoundLevelListener;
|
||||
|
||||
private TextView tv_zhul;
|
||||
|
||||
private SVGAParser parser = new SVGAParser(getContext());
|
||||
private SVGAParser mParser;
|
||||
|
||||
private final SVGAParser parser = new SVGAParser(CommonAppContext.getInstance());
|
||||
|
||||
|
||||
public BaseWheatView(Context context) {
|
||||
@@ -237,7 +247,7 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
|
||||
} else {
|
||||
iv_tag_type.setVisibility(GONE);
|
||||
}
|
||||
AgoraManager.getInstance(getContext()).addSoundLevelListener(new SoundLevelUpdateListener() {
|
||||
AgoraManager.getInstance().addSoundLevelListener(new SoundLevelUpdateListener() {
|
||||
@Override
|
||||
public void onRemoteSoundLevelUpdate(String userId, int soundLevel) {
|
||||
if (mIvRipple == null)
|
||||
@@ -250,10 +260,41 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
|
||||
mIvRipple.setVisibility(INVISIBLE);
|
||||
} else {
|
||||
mIvRipple.setVisibility(VISIBLE);
|
||||
mIvRipple.post(() -> {
|
||||
if (!mIvRipple.isAnimating()) {
|
||||
if (pitBean.getMic_cycle() != null && !pitBean.getMic_cycle().isEmpty()) {
|
||||
if (mParser != null) {
|
||||
mIvRipple.startAnimation();
|
||||
} else {
|
||||
mParser = new SVGAParser(getContext());
|
||||
try {
|
||||
mParser.decodeFromURL(new URL(pitBean.getMic_cycle()), new SVGAParser.ParseCompletion() {
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) {
|
||||
SVGADrawable drawable = new SVGADrawable(svgaVideoEntity);
|
||||
mIvRipple.setImageDrawable(drawable);
|
||||
mIvRipple.startAnimation();
|
||||
}
|
||||
});
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
mIvRipple.startAnimation();
|
||||
}
|
||||
CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(), 1);
|
||||
iv_on_line.setVisibility(GONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,7 +307,34 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
|
||||
} else {
|
||||
mIvRipple.setVisibility(VISIBLE);
|
||||
if (!mIvRipple.isAnimating()) {
|
||||
if (pitBean.getMic_cycle()!=null && !pitBean.getMic_cycle().isEmpty()) {
|
||||
if (mParser != null) {
|
||||
mIvRipple.startAnimation();
|
||||
} else {
|
||||
mParser = new SVGAParser(getContext());
|
||||
try {
|
||||
mParser.decodeFromURL(new URL(pitBean.getMic_cycle()), new SVGAParser.ParseCompletion() {
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) {
|
||||
SVGADrawable drawable = new SVGADrawable(svgaVideoEntity);
|
||||
mIvRipple.setImageDrawable(drawable);
|
||||
mIvRipple.startAnimation();
|
||||
}
|
||||
});
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
|
||||
mIvRipple.startAnimation();
|
||||
}
|
||||
CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(), 1);
|
||||
iv_on_line.setVisibility(GONE);
|
||||
}
|
||||
@@ -456,7 +524,7 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
|
||||
|
||||
@Override
|
||||
public void unRegister(Object obj) {
|
||||
AgoraManager.getInstance(getContext()).removeSoundLevelListener(this);
|
||||
AgoraManager.getInstance().removeSoundLevelListener(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -239,6 +239,7 @@ public class Constants {
|
||||
public static final String FORGOT_PASSWORD = "/api/Login/forgot_password";//忘记密码
|
||||
public static final String CLEAR_LOGIN_INFO = "/api/Login/logout";//忘记密码
|
||||
public static final String CANCEL = "/api/Login/cancel";//注销账号
|
||||
public static final String POST_MODIFY_HIDE_STATUS = "/api/UserData/modify_hide_status";//设置隐身进入
|
||||
public static final String GET_MY_INFO = "/api/User/get_user_info";//点击我的获取个人数据
|
||||
public static final String GET_USER_HOME = "/api/User/get_user_home";//点击获取个人数据
|
||||
|
||||
@@ -407,6 +408,9 @@ public class Constants {
|
||||
public static final String GET_EMOTION = "/api/RoomEmoji/type_list";//表情类型列表
|
||||
public static final String GET_EMOTION_DEATILS = "/api/RoomEmoji/emoji_list";//表情列表
|
||||
public static final String GET_TEMP_KEY = "/api/Upload/getTempKeys";//获取上传cos的临时秘钥
|
||||
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";//爵位购买价格
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
package com.xscm.moduleutil.widget;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewAnimationUtils;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.blankj.utilcode.util.ScreenUtils;
|
||||
import com.xscm.moduleutil.utils.BarUtils;
|
||||
|
||||
/**
|
||||
* com.xscm.moduleutil.widget
|
||||
* qx 首页首充好礼的悬浮框
|
||||
* 2025/11/4
|
||||
*/
|
||||
public class DropHomeView extends LinearLayout {
|
||||
|
||||
private int rightMargin = 0;
|
||||
private float lastX, lastY;
|
||||
private int screenWidth;
|
||||
private int screenHeight; // 添加屏幕高度变量
|
||||
|
||||
public DropHomeView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public DropHomeView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public DropHomeView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
void init() {
|
||||
// 初始化屏幕尺寸
|
||||
screenWidth = ScreenUtils.getScreenWidth();
|
||||
screenHeight = ScreenUtils.getScreenHeight();
|
||||
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//设置初始位置
|
||||
int sh = ScreenUtils.getScreenHeight();
|
||||
int sw = ScreenUtils.getScreenWidth();
|
||||
// setBackgroundResource(R.drawable.bg_home_drop_view);
|
||||
int y = (int) (0.6f * sh) - getHeight();//这是设置展示的纵坐标
|
||||
// 确保Y坐标不会超出屏幕范围
|
||||
y = Math.max(0, Math.min(y, sh - getHeight()));
|
||||
// int x = sw - getWidth();//这是靠右边展示的
|
||||
int x=20 ;//这里这只一小的数值,就是靠左展示的
|
||||
setTranslationX(x);
|
||||
setTranslationY(y);
|
||||
}
|
||||
});
|
||||
|
||||
updateSize();
|
||||
mStatusBarHeight = BarUtils.getStatusBarHeight();
|
||||
}
|
||||
/**
|
||||
* 更新屏幕尺寸信息
|
||||
*/
|
||||
protected void updateSize() {
|
||||
ViewGroup viewGroup = (ViewGroup) getParent();
|
||||
if (viewGroup != null) {
|
||||
mScreenWidth = viewGroup.getWidth();
|
||||
mScreenHeight = viewGroup.getHeight();
|
||||
} else {
|
||||
// 如果父视图为空,使用屏幕的实际宽度和高度
|
||||
mScreenWidth = getResources().getDisplayMetrics().widthPixels;
|
||||
mScreenHeight = getResources().getDisplayMetrics().heightPixels;
|
||||
}
|
||||
}
|
||||
|
||||
boolean starDrap = false;
|
||||
float X1;
|
||||
float X2;
|
||||
float Y1;
|
||||
float Y2;
|
||||
// 记录视图初始位置
|
||||
private float originalX;
|
||||
private float originalY;
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
if (starDrap) return true;
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
X1 = event.getRawX();
|
||||
Y1 = event.getRawY();
|
||||
// 记录视图当前位置
|
||||
originalX = getTranslationX();
|
||||
originalY = getTranslationY();
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
X2 = event.getRawX();
|
||||
Y2 = event.getRawY();
|
||||
Action(X1, X2, Y1, Y2);
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
return starDrap;
|
||||
}
|
||||
|
||||
String TAG = "DropHourlView";
|
||||
|
||||
public boolean Action(float X1, float X2, float Y1, float Y2) {
|
||||
float ComparedX = X2 - X1;//第二次的X坐标的位置减去第一次X坐标的位置,代表X坐标上的变化情况
|
||||
float ComparedY = Y2 - Y1;//同理
|
||||
//当X坐标的变化量的绝对值大于Y坐标的变化量的绝对值,以X坐标的变化情况作为判断依据
|
||||
//上下左右的判断,都在一条直线上,但手指的操作不可能划直线,所有选择变化量大的方向上的量
|
||||
//作为判断依据
|
||||
if (Math.abs(ComparedX) > 30 || Math.abs(ComparedY) > 30) {
|
||||
Log.i(TAG, "Action: 拖动");
|
||||
starDrap = true;
|
||||
// setBackgroundResource(R.drawable.bg_home_drop_view);
|
||||
return true;
|
||||
} else {
|
||||
starDrap = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private float mOriginalRawX;
|
||||
private float mOriginalRawY;
|
||||
private float mOriginalX;
|
||||
private float mOriginalY;
|
||||
protected int mScreenWidth;
|
||||
private int mScreenHeight;
|
||||
private int mStatusBarHeight;
|
||||
|
||||
private void updateViewPosition(MotionEvent event) {
|
||||
// 计算新的Y位置
|
||||
float desY = mOriginalY + event.getRawY() - mOriginalRawY;
|
||||
|
||||
// 限制Y位置不超出屏幕边界
|
||||
if (desY < mStatusBarHeight) {
|
||||
desY = mStatusBarHeight;
|
||||
}
|
||||
if (desY > mScreenHeight - getHeight()) {
|
||||
desY = mScreenHeight - getHeight();
|
||||
}
|
||||
|
||||
// 计算新的X位置
|
||||
float desX = mOriginalX + event.getRawX() - mOriginalRawX;
|
||||
|
||||
// 限制X位置不超出屏幕边界
|
||||
if (desX < 0) {
|
||||
desX = 0;
|
||||
}
|
||||
if (desX > mScreenWidth - getWidth()) {
|
||||
desX = mScreenWidth - getWidth();
|
||||
}
|
||||
|
||||
// 设置视图的新位置
|
||||
setX(desX);
|
||||
setY(desY);
|
||||
}
|
||||
private void changeOriginalTouchParams(MotionEvent event) {
|
||||
mOriginalX = getX();//getX()相对于控件X坐标的距离
|
||||
mOriginalY = getY();
|
||||
mOriginalRawX = event.getRawX();//getRawX()指控件在屏幕上的X坐标
|
||||
mOriginalRawY = event.getRawY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (event == null) {
|
||||
return false;
|
||||
}
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
changeOriginalTouchParams(event);
|
||||
updateSize(); // 添加这行确保尺寸是最新的
|
||||
// ... 其他现有代码 ...
|
||||
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
|
||||
updateViewPosition(event); // 使用更新后的带边界检查的方法
|
||||
|
||||
// setBackgroundResource(R.drawable.bg_home_drop_view);
|
||||
// 使用屏幕绝对坐标计算新位置
|
||||
// float newX = originalX + (event.getRawX() - X1);
|
||||
// float newY = originalY + (event.getRawY() - Y1);
|
||||
//
|
||||
// // 限制X和Y坐标在屏幕范围内
|
||||
// newX = Math.max(0, Math.min(newX, screenWidth - getWidth()));
|
||||
// newY = Math.max(0, Math.min(newY, screenHeight - getHeight()));
|
||||
//
|
||||
// setTranslationX(newX);
|
||||
// setTranslationY(newY);
|
||||
// X2 = event.getRawX();
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
starDrap = false;
|
||||
int sw = ScreenUtils.getScreenWidth();
|
||||
Log.i(TAG, "onTouchEvent: " + sw + "," + X2);
|
||||
boolean isR = getTranslationX() + getWidth() / 2 >= sw / 2;//贴边方向
|
||||
|
||||
// 获取当前Y坐标
|
||||
float currentY = getTranslationY();
|
||||
|
||||
// 创建X轴和Y轴的动画
|
||||
ObjectAnimator animX = ObjectAnimator.ofFloat(this, "translationX", isR ? sw - getWidth() : 0f).setDuration(200);
|
||||
// Y轴保持当前位置,但确保在屏幕范围内
|
||||
currentY = Math.max(0, Math.min(currentY, screenHeight - getHeight()));
|
||||
ObjectAnimator animY = ObjectAnimator.ofFloat(this, "translationY", currentY).setDuration(200);
|
||||
|
||||
animX.start();
|
||||
animY.start();
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public void doRevealAnimation(View mPuppet, boolean flag) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
int[] vLocation = new int[2];
|
||||
getLocationInWindow(vLocation);
|
||||
int centerX = vLocation[0] + getMeasuredWidth() / 2;
|
||||
int centerY = vLocation[1] + getMeasuredHeight() / 2;
|
||||
|
||||
int height = ScreenUtils.getScreenHeight();
|
||||
int width = ScreenUtils.getScreenWidth();
|
||||
int maxRradius = (int) Math.hypot(height, width);
|
||||
Log.e("hei", maxRradius + "");
|
||||
|
||||
if (flag) {
|
||||
mPuppet.setVisibility(VISIBLE);
|
||||
Animator animator = ViewAnimationUtils.createCircularReveal(mPuppet, centerX, centerY, maxRradius, 0);
|
||||
animator.setDuration(600);
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
mPuppet.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
animator.start();
|
||||
flag = false;
|
||||
} else {
|
||||
Animator animator = ViewAnimationUtils.createCircularReveal(mPuppet, centerX, centerY, 0, maxRradius);
|
||||
animator.setDuration(1000);
|
||||
animator.addListener(new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
mPuppet.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
|
||||
}
|
||||
});
|
||||
animator.start();
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.xscm.moduleutil.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Shader;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.appcompat.widget.AppCompatTextView;
|
||||
|
||||
/**
|
||||
* com.xscm.moduleutil.widget
|
||||
* qx 爵位中的文字渐变颜色
|
||||
* 2025/11/8
|
||||
*/
|
||||
public class GradientTextView extends AppCompatTextView {
|
||||
|
||||
public GradientTextView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public GradientTextView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public GradientTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
if (changed) {
|
||||
createGradient();
|
||||
}
|
||||
}
|
||||
|
||||
private void createGradient() {
|
||||
// 获取TextView的宽度
|
||||
int width = getWidth();
|
||||
if (width > 0) {
|
||||
// 创建从左到右的线性渐变 #A292FF -> #FFFFFF -> #A292FF
|
||||
LinearGradient gradient = new LinearGradient(
|
||||
0, 0, width, 0,
|
||||
new int[]{0xFFA292FF, 0xFFFFFFFF, 0xFFA292FF},
|
||||
new float[]{0f, 0.5f, 1f},
|
||||
Shader.TileMode.CLAMP
|
||||
);
|
||||
getPaint().setShader(gradient);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -246,8 +246,8 @@ public class RoomSingSongWheatView extends BaseWheatView {
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
|
||||
|
||||
// 视图从窗口分离时释放资源
|
||||
// releaseResources();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -255,6 +255,13 @@ public class RoomSingSongWheatView extends BaseWheatView {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 远端拉流音频声浪回调
|
||||
*
|
||||
* @param userId
|
||||
* @param soundLevel
|
||||
*/
|
||||
@Override
|
||||
public void onRemoteSoundLevelUpdate(String userId, int soundLevel) {
|
||||
|
||||
|
||||
13
BaseModule/src/main/res/drawable/bg_me_gift_wall.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape android:shape="rectangle"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:startColor="#fff7d1ff"
|
||||
android:endColor="#ffe477ff"
|
||||
android:angle="0"/>
|
||||
<corners
|
||||
android:topLeftRadius="10dp"
|
||||
android:topRightRadius="10dp"
|
||||
android:bottomLeftRadius="10dp"
|
||||
android:bottomRightRadius="10dp"/>
|
||||
</shape>
|
||||
15
BaseModule/src/main/res/drawable/bg_me_wallet.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape android:shape="rectangle"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
|
||||
android:startColor="#FFF1C2"
|
||||
android:endColor="#FFd762"
|
||||
android:angle="0"
|
||||
/>
|
||||
<corners
|
||||
android:topLeftRadius="10dp"
|
||||
android:topRightRadius="10dp"
|
||||
android:bottomLeftRadius="10dp"
|
||||
android:bottomRightRadius="10dp"/>
|
||||
</shape>
|
||||
6
BaseModule/src/main/res/drawable/bg_r4_2a2925.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape android:shape="rectangle"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#2A2925" />
|
||||
<corners android:radius="@dimen/dp_4"/>
|
||||
</shape>
|
||||
6
BaseModule/src/main/res/drawable/bg_r6_2a2a4e.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape android:shape="rectangle"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#4d2a2a4e" />
|
||||
<corners android:topLeftRadius="6dp" android:topRightRadius="6dp" android:bottomLeftRadius="6dp" android:bottomRightRadius="6dp" />
|
||||
</shape>
|
||||
15
BaseModule/src/main/res/drawable/bg_r8_f8f6c7_fffff.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape android:shape="rectangle"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:type="linear"
|
||||
android:useLevel="true"
|
||||
android:startColor="#F8F6C7"
|
||||
android:endColor="#ffffffff"
|
||||
android:angle="0"/>
|
||||
<corners
|
||||
android:topLeftRadius="8dp"
|
||||
android:topRightRadius="8dp"
|
||||
android:bottomLeftRadius="8dp"
|
||||
android:bottomRightRadius="8dp"/>
|
||||
</shape>
|
||||
20
BaseModule/src/main/res/drawable/tab_indicator_bg.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- 用item标签限制整体尺寸:maxWidth=100dp,height=10dp(与tabIndicatorHeight一致) -->
|
||||
<item
|
||||
android:height="@dimen/dp_25"
|
||||
android:gravity="center"
|
||||
android:maxWidth="@dimen/dp_20">
|
||||
<!-- 最大宽度(根据需求调整) -->
|
||||
<!-- 固定高度(与tabIndicatorHeight匹配) -->
|
||||
<!-- 图片在item内居中 -->
|
||||
<!-- 嵌套bitmap设置图片资源和缩放模式 -->
|
||||
<bitmap
|
||||
android:dither="true"
|
||||
android:scaleType="center"
|
||||
android:src="@mipmap/tab_dy" />
|
||||
<!-- 你的图片资源 -->
|
||||
<!-- 等比例缩放,确保图片在maxWidth和height内完整显示 -->
|
||||
<!-- 抗锯齿优化 -->
|
||||
</item>
|
||||
</layer-list>
|
||||
@@ -5,15 +5,13 @@
|
||||
android:id="@+id/cl_gift"
|
||||
android:layout_width="@dimen/dp_77"
|
||||
android:layout_height="@dimen/dp_119"
|
||||
android:background="@mipmap/gift_bj"
|
||||
>
|
||||
android:background="@mipmap/gift_bj">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_iv_down_on"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:ignore="MissingConstraints"
|
||||
>
|
||||
tools:ignore="MissingConstraints">
|
||||
|
||||
|
||||
<ImageView
|
||||
@@ -44,8 +42,7 @@
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
/>
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_gift_name"
|
||||
@@ -63,10 +60,10 @@
|
||||
android:id="@+id/tv_gift_price"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="1"
|
||||
android:layout_marginBottom="@dimen/dp_5"
|
||||
android:drawableLeft="@mipmap/jinb"
|
||||
android:drawablePadding="@dimen/dp_3"
|
||||
android:layout_marginBottom="@dimen/dp_5"
|
||||
android:text="1"
|
||||
android:textColor="@color/color_FFFFBC00"
|
||||
android:textSize="11sp"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/iv_gift_pic"
|
||||
@@ -79,13 +76,22 @@
|
||||
android:layout_height="@dimen/dp_13"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:background="@mipmap/text_bj"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:gravity="center"
|
||||
android:text="x30"
|
||||
android:textColor="@color/color_FF333333"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:visibility="gone"/>
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_gift_select"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@mipmap/noble_is_lock"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<com.xscm.moduleutil.widget.GifAvatarOvalView
|
||||
@@ -17,7 +19,7 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintWidth_percent="0.90154"
|
||||
android:src="@mipmap/default_avatar"
|
||||
app:riv_oval="true" />
|
||||
app:riv_oval="true"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_sex"
|
||||
@@ -40,7 +42,27 @@
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dp_1"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintGuide_percent="0.58"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_frame_bg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="fitXY"
|
||||
tools:src="@mipmap/me_sj"
|
||||
app:layout_constraintTop_toTopOf="@+id/guideline"
|
||||
app:layout_constraintWidth_default="spread"
|
||||
app:layout_constraintHeight_default="spread"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_online"
|
||||
@@ -53,6 +75,6 @@
|
||||
app:layout_constraintHorizontal_bias="0.9"
|
||||
app:layout_constraintStart_toStartOf="@id/riv"
|
||||
app:layout_constraintTop_toTopOf="@id/riv"
|
||||
app:layout_constraintVertical_bias="0.9" />
|
||||
app:layout_constraintVertical_bias="0.9"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
BIN
BaseModule/src/main/res/mipmap-hdpi/arrow_right.png
Normal file
|
After Width: | Height: | Size: 210 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/beautiful.webp
Normal file
|
After Width: | Height: | Size: 896 B |
|
Before Width: | Height: | Size: 4.4 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/cp_tx_k.webp
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/gift_wall_liang.webp
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/gift_wall_no_liang.webp
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/icon_no.webp
Normal file
|
After Width: | Height: | Size: 560 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/icon_noble_d.webp
Normal file
|
After Width: | Height: | Size: 374 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/icon_noble_gz.webp
Normal file
|
After Width: | Height: | Size: 632 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/icon_noble_title.webp
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/icon_yes.webp
Normal file
|
After Width: | Height: | Size: 576 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_edit.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_gh.webp
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_help.webp
Normal file
|
After Width: | Height: | Size: 676 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_home.webp
Normal file
|
After Width: | Height: | Size: 734 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_income.webp
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_invitation.webp
Normal file
|
After Width: | Height: | Size: 684 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_my_bag.webp
Normal file
|
After Width: | Height: | Size: 662 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_noble_bj.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_noble_image.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_noble_no.webp
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_noble_xf.webp
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_opinion.webp
Normal file
|
After Width: | Height: | Size: 514 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_recharge.webp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_setting.webp
Normal file
|
After Width: | Height: | Size: 952 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_show_store.webp
Normal file
|
After Width: | Height: | Size: 826 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_sj.webp
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_test.webp
Normal file
|
After Width: | Height: | Size: 626 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/me_zy.webp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/my_dan.webp
Normal file
|
After Width: | Height: | Size: 756 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/my_noblesse.webp
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_cz_ts.webp
Normal file
|
After Width: | Height: | Size: 744 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_details_bj.webp
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_details_tq.webp
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_duib.webp
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_h_kt.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_is_lock.webp
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_kt.webp
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_ljkt.webp
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_ljsj.webp
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_seccer.webp
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_sj.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_xf.webp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_yxq.webp
Normal file
|
After Width: | Height: | Size: 508 B |
BIN
BaseModule/src/main/res/mipmap-hdpi/noble_zf_bj.webp
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/personality.webp
Normal file
|
After Width: | Height: | Size: 598 B |
|
Before Width: | Height: | Size: 3.9 KiB |
BIN
BaseModule/src/main/res/mipmap-hdpi/ranking_user_cp_k.webp
Normal file
|
After Width: | Height: | Size: 948 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 730 B |
BIN
BaseModule/src/main/res/mipmap-xhdpi/arrow_right.png
Normal file
|
After Width: | Height: | Size: 176 B |
BIN
BaseModule/src/main/res/mipmap-xhdpi/beautiful.webp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
BIN
BaseModule/src/main/res/mipmap-xhdpi/cp_tx_k.webp
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
BaseModule/src/main/res/mipmap-xhdpi/gift_wall_liang.webp
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
BaseModule/src/main/res/mipmap-xhdpi/gift_wall_no_liang.webp
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 365 B |
BIN
BaseModule/src/main/res/mipmap-xhdpi/hourly_d.webp
Normal file
|
After Width: | Height: | Size: 212 B |
|
Before Width: | Height: | Size: 16 KiB |
BIN
BaseModule/src/main/res/mipmap-xhdpi/hourly_xlh_status.webp
Normal file
|
After Width: | Height: | Size: 5.6 KiB |