Compare commits
243 Commits
branch_new
...
branch_new
| Author | SHA1 | Date | |
|---|---|---|---|
| 1669932feb | |||
| be4356f317 | |||
| 9c7567dfd1 | |||
| 88ce3ac161 | |||
| 48506a075e | |||
| cb79afaab6 | |||
| dfc64d7a14 | |||
| 3977e3e158 | |||
| 877862e507 | |||
| 5ce33aeeb1 | |||
| 0afb5dbbfd | |||
| 3530c10772 | |||
| 5b27d91278 | |||
| 513cc23d9c | |||
| 7aa294c3a9 | |||
| 88ce0205fb | |||
| 3d0fb12565 | |||
| cb16dbb9e1 | |||
| 8ce7a9e5de | |||
| 8db507718c | |||
| e23578838c | |||
| 973fac58a4 | |||
| 8a587210cf | |||
| 8d7de418bb | |||
| 24c4af95b4 | |||
| 9450a351c5 | |||
| 9f8f8137d1 | |||
| d07ca522ab | |||
| 08c51e0273 | |||
| 60b8e901b5 | |||
| 885d6b1e7d | |||
| 3f2989664c | |||
| 76f499f022 | |||
| 1048b8f46e | |||
| 78f290eef8 | |||
| 3f49cf3790 | |||
| 9ab1f171f8 | |||
| 4e8058f200 | |||
| 4fdd5578a8 | |||
| 163340a691 | |||
| bf609a3964 | |||
| e6232f5aa2 | |||
| 0ae0cff87a | |||
| ac7a3b1325 | |||
| 16bd6d7e1a | |||
| 838a2ec64a | |||
| 87782e9caa | |||
| 0a0875fb88 | |||
| 725add62ac | |||
| 59b48e0b0f | |||
| e5f77b626e | |||
| 99b3350329 | |||
| 883a96f2c7 | |||
| 8e86ba68d0 | |||
| bf507a6264 | |||
| 716cafc62b | |||
| 267b8a0aea | |||
| 60fff84aaf | |||
| 0a968babef | |||
| b3c1ae647d | |||
| fcc690db64 | |||
| 476de595da | |||
| a4c21485a2 | |||
| e24f217ab4 | |||
| a07ee5cfe9 | |||
| 60c97447dd | |||
| b201787513 | |||
| 064338e838 | |||
| 0a0771d5a3 | |||
| f82e5c8348 | |||
| d7a27baf5c | |||
| a3551e2e33 | |||
| a1fcc56551 | |||
| cdb5f9b794 | |||
| e9ab535b2d | |||
| f5b4dde3c6 | |||
| f4f27c2c94 | |||
| 268c3cdd98 | |||
| dde6ccd578 | |||
| f01d903d2f | |||
| e3bad8ddab | |||
| 2b29b0de18 | |||
| 6e5e8abc0b | |||
| 38d1c266d6 | |||
| 6a22259c16 | |||
| b1523c2f2a | |||
| 8f4c2d1b83 | |||
| 0fd8ecd73d | |||
| 6b87252a51 | |||
| 64ced88287 | |||
| 716f292fa5 | |||
| 39b9ea73a1 | |||
| c67b07e3b9 | |||
| 5a1edb6c4a | |||
| a034e5e954 | |||
| 15ed708853 | |||
| ca4d9ea20a | |||
| 84fa4ed1f3 | |||
| 4c7a2ae3b7 | |||
| 34f4d980ad | |||
| 2589b97f29 | |||
| 5946cf97b9 | |||
| 0be33ec918 | |||
| 8264974d85 | |||
| 54b3312eac | |||
| 0ff889d72a | |||
| 7436649f71 | |||
| ea85b71e2f | |||
| 58c39962fa | |||
| 36fbc88f21 | |||
| 97f30ce233 | |||
| c355fd66d6 | |||
| 2e61fa5e4d | |||
| b5fcf232fe | |||
| 9627a476f7 | |||
| d5cbb5008c | |||
| 1b560a3806 | |||
| 34552f45ec | |||
| ab228eb05d | |||
| a8328ac8b9 | |||
| d2f2829ca2 | |||
| 43600c60c0 | |||
| e12bb36fe5 | |||
| e74bfde545 | |||
| 0b37364a11 | |||
| ac09992b01 | |||
| 26a40f8ffb | |||
| a8ae4a61c2 | |||
| fe78c968f2 | |||
| 9fbb12819f | |||
| 6338728ddf | |||
| 50d509dc12 | |||
| 1c4384f5d5 | |||
| 5f7bac8a12 | |||
| 3dcdd1e599 | |||
| d1cd2aeef7 | |||
| b76136b604 | |||
| 2f0f5ae5e8 | |||
| d48f13f266 | |||
| 5cc393fe06 | |||
| 44ebb14fb3 | |||
| 9ef4f27ed9 | |||
| 43ea35d3a2 | |||
| 3efe9c9146 | |||
| b473751913 | |||
| 0e830e411a | |||
| 5d17bf8de0 | |||
| f77b5ba4d7 | |||
| aa96aa4a3b | |||
| 8bd22ae41a | |||
| 510aa804ab | |||
| c2fd1df529 | |||
| 479e039e56 | |||
| 9126676599 | |||
| 7f881260aa | |||
| 3f1b8ee2fa | |||
| 7b6be82c54 | |||
| aab29ea784 | |||
| ab556d2519 | |||
| 4f48c55cf6 | |||
| 359f93aac7 | |||
| e6892d533c | |||
| 67c56b2d4f | |||
| fa6f40c369 | |||
| 9476655ba3 | |||
| 27485de14f | |||
| d6efdefc99 | |||
| 8b24d3ace5 | |||
| 730b94cff5 | |||
| e3751528ad | |||
| ff9677fa6d | |||
| be2306b50c | |||
| 2adc4948c7 | |||
| 6b1614d768 | |||
| 8fec498dba | |||
| e26101c35f | |||
| bb31bafa55 | |||
| 826469178e | |||
| addd97a434 | |||
| 84fb05044a | |||
| 342cfd347c | |||
| 214c339e93 | |||
| bb54407c62 | |||
| c22e88eebb | |||
| 0444a906ba | |||
| e4ed3eb9a1 | |||
| eee16d3a4a | |||
| e3d4240a82 | |||
| b7320cb51a | |||
| 4a83bbda2d | |||
| f0451bfeea | |||
| 7e6d174297 | |||
| 8b24ac310e | |||
| 9bf2de01d4 | |||
| c7018cce42 | |||
| 320f742b87 | |||
| ec2e754806 | |||
| daba3d9872 | |||
| 435d2084d1 | |||
| e3744843d9 | |||
| 9774b0bb2c | |||
| ed7632c142 | |||
| f5287becee | |||
| e21345ba61 | |||
| ca3580ad28 | |||
| 837231f4f0 | |||
| 53b9f0f034 | |||
| f34a67c2e8 | |||
| 6bd210217a | |||
| 6c8065711d | |||
| 5c607c58ae | |||
| f2363dad01 | |||
| 07dbffaa5a | |||
| b028ec883b | |||
| 552e238254 | |||
| 3fde4df00f | |||
| 471a0453fa | |||
| 420afc7a1e | |||
| 6130accb48 | |||
| e2b0c9ce8c | |||
| 894b397537 | |||
| 6207705d2a | |||
| f5fea27595 | |||
| c388d765d4 | |||
| 952621baaa | |||
| df499aaa6c | |||
| 3d8e152cd8 | |||
| 727e343d1f | |||
| ef27636564 | |||
| aa778ca1de | |||
| 90077d24f6 | |||
| 81b41ef392 | |||
| c2714ff68a | |||
| 1fbece3e62 | |||
| 7f4843b023 | |||
| ec3f3d6233 | |||
| 1b06d5725f | |||
| 0874998249 | |||
| b611147176 | |||
| ac9d9b19fd | |||
| ea2b45c1be | |||
| 19bc9dbad8 | |||
| 4b356a6ce4 |
2
.idea/.name
generated
2
.idea/.name
generated
@@ -1 +1 @@
|
||||
秘地
|
||||
羽声语音
|
||||
@@ -44,7 +44,6 @@ android {
|
||||
kotlinOptions {
|
||||
jvmTarget = '11'
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
// exclude 'lib/arm64-v8a/libagora-fdkaac.so'
|
||||
}
|
||||
|
||||
BIN
BaseModule/src/main/assets/prize_call_box_default.svga
Normal file
BIN
BaseModule/src/main/assets/prize_call_box_default.svga
Normal file
Binary file not shown.
BIN
BaseModule/src/main/assets/prize_call_open_box.svga
Normal file
BIN
BaseModule/src/main/assets/prize_call_open_box.svga
Normal file
Binary file not shown.
BIN
BaseModule/src/main/assets/room_wish_crystal_animation.svga
Normal file
BIN
BaseModule/src/main/assets/room_wish_crystal_animation.svga
Normal file
Binary file not shown.
@@ -5,6 +5,7 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
@@ -29,6 +30,7 @@ import com.blankj.utilcode.util.BarUtils;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
import com.hjq.toast.ToastUtils;
|
||||
import com.xscm.moduleutil.R;
|
||||
import com.xscm.moduleutil.base.CommonAppContext;
|
||||
import com.xscm.moduleutil.dialog.LoadingDialog;
|
||||
import com.xscm.moduleutil.utils.BackgroundManager;
|
||||
import com.xscm.moduleutil.utils.ColorManager;
|
||||
@@ -83,8 +85,10 @@ public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends
|
||||
@SuppressLint("UnspecifiedRegisterReceiverFlag")
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
initFestivalTheme(CommonAppContext.getInstance().is_open);
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().getDecorView().setBackgroundResource(R.mipmap.log_bj);
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||
// getWindow().getDecorView().setBackgroundResource(R.attr.app_bg_img);
|
||||
setContentView(getLayoutId());
|
||||
doDone();
|
||||
// 隐藏标题栏
|
||||
@@ -103,7 +107,7 @@ public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends
|
||||
// 注册背景更新监听器
|
||||
BackgroundManager.getInstance().addListener(this);
|
||||
// 尝试加载网络背景
|
||||
loadNetworkBackground();
|
||||
// loadNetworkBackground();
|
||||
// 注册颜色变化监听器
|
||||
ColorManager.getInstance().addColorChangeListener(this);
|
||||
|
||||
@@ -114,6 +118,25 @@ public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends
|
||||
EventBus.getDefault().register(this);
|
||||
}
|
||||
|
||||
// 节日判断+主题切换核心方法
|
||||
private void initFestivalTheme(int currentFestival) {
|
||||
switch (currentFestival) {
|
||||
case 0:
|
||||
setTheme(R.style.AppTheme_CustomAttrs);
|
||||
break;
|
||||
case 1:
|
||||
setTheme(R.style.AppTheme_Spring_CustomAttrs);
|
||||
break;
|
||||
case 2:
|
||||
setTheme(R.style.AppTheme_newYear_CustomAttrs);
|
||||
break;
|
||||
default:
|
||||
// 默认皮肤
|
||||
setTheme(R.style.AppTheme_CustomAttrs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 在Activity中
|
||||
private static final int REQUEST_OVERLAY_PERMISSION = 1001;
|
||||
|
||||
@@ -179,28 +202,8 @@ public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends
|
||||
|
||||
protected void loadNetworkBackground() {
|
||||
// 只有当已经有背景URL时才加载
|
||||
String backgroundUrl = BackgroundManager.getInstance().getBackgroundUrl();
|
||||
if (backgroundUrl != null && !backgroundUrl.isEmpty()) {
|
||||
// 检查是否有已加载的drawable
|
||||
Drawable cachedDrawable = BackgroundManager.getInstance().getBackgroundDrawable();
|
||||
if (cachedDrawable != null) {
|
||||
getWindow().getDecorView().setBackground(cachedDrawable);
|
||||
} else {
|
||||
// 加载网络背景
|
||||
BackgroundManager.getInstance().loadBackgroundDrawable(this, new BackgroundManager.BackgroundLoadCallback() {
|
||||
@Override
|
||||
public void onLoadSuccess(Drawable drawable) {
|
||||
getWindow().getDecorView().setBackground(drawable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFailed() {
|
||||
// 加载失败时使用默认背景
|
||||
getWindow().getDecorView().setBackgroundResource(R.mipmap.activity_bj);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// int backgroundUrl = BackgroundManager.getInstance().getBackgroundUrl();
|
||||
// getWindow().getDecorView().setBackgroundResource(backgroundUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -213,7 +216,7 @@ public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends
|
||||
|
||||
// 提供一个方法供子类调用,用于设置背景URL
|
||||
protected void setNetworkBackgroundUrl(String url) {
|
||||
BackgroundManager.getInstance().setBackgroundUrl(url);
|
||||
// BackgroundManager.getInstance().setBackgroundUrl(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -256,13 +259,14 @@ public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
EventBus.getDefault().unregister(this);
|
||||
|
||||
super.finish();
|
||||
LogUtils.e(this.getComponentName()+"========finish");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
EventBus.getDefault().unregister(this);
|
||||
// 移除背景更新监听器
|
||||
BackgroundManager.getInstance().removeListener(this);
|
||||
// 移除颜色变化监听器
|
||||
|
||||
@@ -117,6 +117,7 @@ public class AppUpdateDialog extends BaseDialog<DialogAppUpdateBinding> implemen
|
||||
mProgressDialog.dismiss();
|
||||
}
|
||||
try {
|
||||
LogUtils.e("installAppSuccess",localPath);
|
||||
AppUtils.installApp(localPath);
|
||||
} catch (Exception e) {
|
||||
Logger.e("installAppError", e);
|
||||
|
||||
@@ -186,7 +186,7 @@ public class CirleListAdapter extends BaseQuickAdapter<CircleListBean, BaseViewH
|
||||
helper.getView(R.id.dy_lookmore_tv).setVisibility(GONE);
|
||||
helper.getView(R.id.dy_content_tv).setVisibility(GONE);
|
||||
} else {
|
||||
helper.getView(R.id.dy_lookmore_tv).setVisibility(VISIBLE);
|
||||
helper.getView(R.id.dy_lookmore_tv).setVisibility(GONE);
|
||||
helper.getView(R.id.dy_content_tv).setVisibility(VISIBLE);
|
||||
}
|
||||
helper.getView(R.id.dy_lookmore_tv).getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
|
||||
@@ -196,7 +196,7 @@ public class CirleListAdapter extends BaseQuickAdapter<CircleListBean, BaseViewH
|
||||
TextView view = helper.getView(R.id.dy_content_tv);
|
||||
int lineCount = view.getLineCount();
|
||||
if (lineCount >= 7) {
|
||||
helper.getView(R.id.dy_lookmore_tv).setVisibility(VISIBLE);
|
||||
helper.getView(R.id.dy_lookmore_tv).setVisibility(GONE);
|
||||
helper.getView(R.id.dy_content_tv).getViewTreeObserver().removeOnPreDrawListener(this);//销毁
|
||||
} else {
|
||||
helper.getView(R.id.dy_lookmore_tv).setVisibility(GONE);
|
||||
|
||||
@@ -14,8 +14,11 @@ import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.xscm.moduleutil.R;
|
||||
import com.xscm.moduleutil.bean.GiftPackBean;
|
||||
import com.xscm.moduleutil.event.RoomGiftPackToEvent;
|
||||
@@ -31,7 +34,7 @@ import java.util.List;
|
||||
* @Time 2025年7月29日23:36:25$ $
|
||||
* @Description 背包礼物适配器$
|
||||
*/
|
||||
public class GiftPackAdapter extends BaseAdapter {
|
||||
public class GiftPackAdapter extends BaseQuickAdapter<GiftPackBean, BaseViewHolder> {
|
||||
private final List<GiftPackBean> mDatas;
|
||||
private final LayoutInflater inflater;
|
||||
private final Context mContext;
|
||||
@@ -47,6 +50,7 @@ public class GiftPackAdapter extends BaseAdapter {
|
||||
private final int pageSize = 100;
|
||||
|
||||
public GiftPackAdapter(Context context, List<GiftPackBean> mDatas, int curIndex, String type) {
|
||||
super(R.layout.item_gift_room, mDatas);
|
||||
inflater = LayoutInflater.from(context);
|
||||
this.mDatas = mDatas;
|
||||
this.curIndex = curIndex;
|
||||
@@ -60,14 +64,45 @@ public class GiftPackAdapter extends BaseAdapter {
|
||||
* 如果够,则直接返回每一页显示的最大条目个数pageSize,
|
||||
* 如果不够,则有几项返回几,(mDatas.size() - curIndex * pageSize);(也就是最后一页的时候就显示剩余item)
|
||||
*/
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mDatas.size() > (curIndex + 1) * pageSize ? pageSize : (mDatas.size() - curIndex * pageSize);
|
||||
}
|
||||
// @Override
|
||||
// public int getCount() {
|
||||
// return mDatas.size() > (curIndex + 1) * pageSize ? pageSize : (mDatas.size() - curIndex * pageSize);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public GiftPackBean getItem(int position) {
|
||||
// return mDatas.get(position + curIndex * pageSize);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public GiftPackBean getItem(int position) {
|
||||
return mDatas.get(position + curIndex * pageSize);
|
||||
protected void convert(@NonNull BaseViewHolder helper, GiftPackBean giftModel) {
|
||||
helper.getView(R.id.cl_gift).setOnClickListener(v -> {
|
||||
// RoonGiftModel clickedModel = (RoonGiftModel) v.getTag();
|
||||
EventBus.getDefault().post(new RoomGiftPackToEvent(this, giftModel, 2));
|
||||
|
||||
});
|
||||
helper.setVisible(R.id.integral, true).setText(R.id.integral, "x" + giftModel.getNum());
|
||||
helper.setText(R.id.tv_gift_name, giftModel.getGift_name());
|
||||
|
||||
//设置礼物价格
|
||||
String surplusTxt = giftModel.getGift_price();
|
||||
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(surplusTxt);
|
||||
//ForegroundColorSpan 为文字前景色,BackgroundColorSpan为文字背景色
|
||||
ForegroundColorSpan redSpan = new ForegroundColorSpan(mContext.getResources().getColor(R.color.color_FFA9A9A9));
|
||||
stringBuilder.setSpan(redSpan, surplusTxt.length(), surplusTxt.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//修改最后两个字体的颜色
|
||||
helper.setText(R.id.tv_gift_price,stringBuilder);
|
||||
|
||||
//加载礼物图片
|
||||
ImageUtils.loadImageView(giftModel.getBase_image(),helper.getView(R.id.iv_gift_pic));
|
||||
//设置选中后的样式
|
||||
|
||||
if (giftModel.isChecked()) {//被选中
|
||||
helper.getView(R.id.cl_iv_down_on).setBackgroundResource(R.mipmap.room_gift_bjx);
|
||||
helper.setVisible(R.id.iv_down_on, false);
|
||||
} else {
|
||||
helper.setVisible(R.id.iv_down_on, false);
|
||||
helper.getView(R.id.cl_iv_down_on).setBackgroundResource(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -107,68 +142,68 @@ public class GiftPackAdapter extends BaseAdapter {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressLint({"SetTextI18n", "ClickableViewAccessibility"})
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
GiftPackAdapter.ViewHolder viewHolder;
|
||||
GiftPackBean giftModel = getItem(position);
|
||||
if (convertView == null) {
|
||||
convertView = inflater.inflate(R.layout.item_gift_room, parent, false);
|
||||
viewHolder = new GiftPackAdapter.ViewHolder();
|
||||
viewHolder.tv_gift_name = (TextView) convertView.findViewById(R.id.tv_gift_name);
|
||||
viewHolder.tv_gift_price = (TextView) convertView.findViewById(R.id.tv_gift_price);
|
||||
viewHolder.iv_gift_pic = (ImageView) convertView.findViewById(R.id.iv_gift_pic);
|
||||
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.integral = (TextView) convertView.findViewById(R.id.integral);
|
||||
viewHolder.im_heart = (ImageView) convertView.findViewById(R.id.im_heartssss);
|
||||
convertView.setTag(viewHolder);
|
||||
} else {
|
||||
viewHolder = (GiftPackAdapter.ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
viewHolder.item_layout.setOnClickListener(v -> {
|
||||
// RoonGiftModel clickedModel = (RoonGiftModel) v.getTag();
|
||||
EventBus.getDefault().post(new RoomGiftPackToEvent(this, giftModel, 2));
|
||||
|
||||
});
|
||||
viewHolder.integral.setVisibility(View.VISIBLE);
|
||||
viewHolder.integral.setText("x"+giftModel.getNum());
|
||||
//设置礼物名字
|
||||
viewHolder.tv_gift_name.setText(giftModel.getGift_name());
|
||||
//设置礼物价格
|
||||
String surplusTxt = giftModel.getGift_price();
|
||||
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(surplusTxt);
|
||||
//ForegroundColorSpan 为文字前景色,BackgroundColorSpan为文字背景色
|
||||
ForegroundColorSpan redSpan = new ForegroundColorSpan(mContext.getResources().getColor(R.color.color_FFA9A9A9));
|
||||
stringBuilder.setSpan(redSpan, surplusTxt.length(), surplusTxt.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//修改最后两个字体的颜色
|
||||
viewHolder.tv_gift_price.setText(stringBuilder);
|
||||
// viewHolder.item_layout.setTag(R.id.id_gift_tag, giftModel);
|
||||
|
||||
//加载礼物图片
|
||||
ImageUtils.loadImageView(giftModel.getBase_image(), viewHolder.iv_gift_pic);
|
||||
//设置选中后的样式
|
||||
|
||||
if (giftModel.isChecked()) {//被选中
|
||||
viewHolder.cl_iv_down_on.setBackgroundResource(R.mipmap.room_gift_bjx);
|
||||
viewHolder.ivDownOn.setVisibility(View.GONE);
|
||||
} else {
|
||||
viewHolder.ivDownOn.setVisibility(View.GONE);
|
||||
viewHolder.cl_iv_down_on.setBackgroundResource(0);
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
|
||||
static class ViewHolder {
|
||||
public ConstraintLayout item_layout;
|
||||
public TextView tv_gift_name, tv_gift_price, integral;
|
||||
public ImageView iv_gift_pic;
|
||||
public TextView tv_gift_change_love_values;
|
||||
public ImageView ivDownOn;
|
||||
public ConstraintLayout cl_iv_down_on;
|
||||
public ImageView im_heart;
|
||||
}
|
||||
// @Override
|
||||
// @SuppressLint({"SetTextI18n", "ClickableViewAccessibility"})
|
||||
// public View getView(int position, View convertView, ViewGroup parent) {
|
||||
// GiftPackAdapter.ViewHolder viewHolder;
|
||||
// GiftPackBean giftModel = getItem(position);
|
||||
// if (convertView == null) {
|
||||
// convertView = inflater.inflate(R.layout.item_gift_room, parent, false);
|
||||
// viewHolder = new GiftPackAdapter.ViewHolder();
|
||||
// viewHolder.tv_gift_name = (TextView) convertView.findViewById(R.id.tv_gift_name);
|
||||
// viewHolder.tv_gift_price = (TextView) convertView.findViewById(R.id.tv_gift_price);
|
||||
// viewHolder.iv_gift_pic = (ImageView) convertView.findViewById(R.id.iv_gift_pic);
|
||||
// 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.integral = (TextView) convertView.findViewById(R.id.integral);
|
||||
// viewHolder.im_heart = (ImageView) convertView.findViewById(R.id.im_heartssss);
|
||||
// convertView.setTag(viewHolder);
|
||||
// } else {
|
||||
// viewHolder = (GiftPackAdapter.ViewHolder) convertView.getTag();
|
||||
// }
|
||||
//
|
||||
// viewHolder.item_layout.setOnClickListener(v -> {
|
||||
//// RoonGiftModel clickedModel = (RoonGiftModel) v.getTag();
|
||||
// EventBus.getDefault().post(new RoomGiftPackToEvent(this, giftModel, 2));
|
||||
//
|
||||
// });
|
||||
// viewHolder.integral.setVisibility(View.VISIBLE);
|
||||
// viewHolder.integral.setText("x"+giftModel.getNum());
|
||||
// //设置礼物名字
|
||||
// viewHolder.tv_gift_name.setText(giftModel.getGift_name());
|
||||
// //设置礼物价格
|
||||
// String surplusTxt = giftModel.getGift_price();
|
||||
// SpannableStringBuilder stringBuilder = new SpannableStringBuilder(surplusTxt);
|
||||
// //ForegroundColorSpan 为文字前景色,BackgroundColorSpan为文字背景色
|
||||
// ForegroundColorSpan redSpan = new ForegroundColorSpan(mContext.getResources().getColor(R.color.color_FFA9A9A9));
|
||||
// stringBuilder.setSpan(redSpan, surplusTxt.length(), surplusTxt.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//修改最后两个字体的颜色
|
||||
// viewHolder.tv_gift_price.setText(stringBuilder);
|
||||
//// viewHolder.item_layout.setTag(R.id.id_gift_tag, giftModel);
|
||||
//
|
||||
// //加载礼物图片
|
||||
// ImageUtils.loadImageView(giftModel.getBase_image(), viewHolder.iv_gift_pic);
|
||||
// //设置选中后的样式
|
||||
//
|
||||
// if (giftModel.isChecked()) {//被选中
|
||||
// viewHolder.cl_iv_down_on.setBackgroundResource(R.mipmap.room_gift_bjx);
|
||||
// viewHolder.ivDownOn.setVisibility(View.GONE);
|
||||
// } else {
|
||||
// viewHolder.ivDownOn.setVisibility(View.GONE);
|
||||
// viewHolder.cl_iv_down_on.setBackgroundResource(0);
|
||||
// }
|
||||
//
|
||||
// return convertView;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// static class ViewHolder {
|
||||
// public ConstraintLayout item_layout;
|
||||
// public TextView tv_gift_name, tv_gift_price, integral;
|
||||
// public ImageView iv_gift_pic;
|
||||
// public TextView tv_gift_change_love_values;
|
||||
// public ImageView ivDownOn;
|
||||
// public ConstraintLayout cl_iv_down_on;
|
||||
// public ImageView im_heart;
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -17,8 +18,12 @@ import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.hjq.toast.ToastUtils;
|
||||
import com.xscm.moduleutil.R;
|
||||
import com.xscm.moduleutil.bean.RoonGiftModel;
|
||||
@@ -30,7 +35,7 @@ import org.greenrobot.eventbus.EventBus;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
public class GiftRoomAdapter extends BaseAdapter {
|
||||
public class GiftRoomAdapter extends BaseQuickAdapter<RoonGiftModel, BaseViewHolder> {
|
||||
private final List<RoonGiftModel> mDatas;
|
||||
private final LayoutInflater inflater;
|
||||
private final Context mContext;
|
||||
@@ -46,7 +51,7 @@ public class GiftRoomAdapter extends BaseAdapter {
|
||||
private final int pageSize = 100;
|
||||
|
||||
public GiftRoomAdapter(Context context, List<RoonGiftModel> mDatas, int curIndex, String type) {
|
||||
|
||||
super(R.layout.item_gift_room);
|
||||
this.mDatas = mDatas;
|
||||
this.curIndex = curIndex;
|
||||
this.mContext = context;
|
||||
@@ -60,19 +65,93 @@ public class GiftRoomAdapter extends BaseAdapter {
|
||||
* 如果够,则直接返回每一页显示的最大条目个数pageSize,
|
||||
* 如果不够,则有几项返回几,(mDatas.size() - curIndex * pageSize);(也就是最后一页的时候就显示剩余item)
|
||||
*/
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mDatas.size() > (curIndex + 1) * pageSize ? pageSize : (mDatas.size() - curIndex * pageSize);
|
||||
}
|
||||
// @Override
|
||||
// public int getCount() {
|
||||
// return mDatas !=null ? mDatas.size() : 0;
|
||||
//// return mDatas.size() > (curIndex + 1) * pageSize ? pageSize : (mDatas.size() - curIndex * pageSize);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public RoonGiftModel getItem(int position) {
|
||||
// return mDatas.get(position);
|
||||
//// return mDatas.get(position + curIndex * pageSize);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public RoonGiftModel getItem(int position) {
|
||||
return mDatas.get(position + curIndex * pageSize);
|
||||
protected void convert(@NonNull BaseViewHolder helper, RoonGiftModel giftModel) {
|
||||
helper.getView(R.id.cl_gift).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) {
|
||||
helper.setVisible(R.id.iv_gift_select,false);
|
||||
} else {
|
||||
helper.setVisible(R.id.iv_gift_select,true);
|
||||
}
|
||||
if (TextUtils.isEmpty(giftModel.getIcon())) {
|
||||
helper.setVisible(R.id.im_heartssss,false);
|
||||
}else {
|
||||
helper.setVisible(R.id.im_heartssss,true);
|
||||
ImageUtils.loadHead(giftModel.getIcon(), helper.getView(R.id.im_heartssss));
|
||||
}
|
||||
|
||||
//设置礼物名字
|
||||
helper.setText(R.id.tv_gift_name,giftModel.getGift_name());
|
||||
if (TextUtils.isEmpty(giftModel.getNum())){
|
||||
helper.setVisible(R.id.integral, false);
|
||||
}else {
|
||||
helper.setVisible(R.id.integral, true).setText(R.id.integral, "x" + giftModel.getNum());
|
||||
}
|
||||
|
||||
//设置礼物价格
|
||||
String surplusTxt = giftModel.getGift_price();
|
||||
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(surplusTxt);
|
||||
//ForegroundColorSpan 为文字前景色,BackgroundColorSpan为文字背景色
|
||||
ForegroundColorSpan redSpan = new ForegroundColorSpan(mContext.getResources().getColor(R.color.color_FFA9A9A9));
|
||||
stringBuilder.setSpan(redSpan, surplusTxt.length(), surplusTxt.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//修改最后两个字体的颜色
|
||||
helper.setText(R.id.tv_gift_price,stringBuilder);
|
||||
// viewHolder.item_layout.setTag(R.id.id_gift_tag, giftModel);
|
||||
|
||||
//加载礼物图片
|
||||
ImageUtils.loadImageView(giftModel.getBase_image(), helper.getView(R.id.iv_gift_pic));
|
||||
//设置选中后的样式
|
||||
|
||||
|
||||
if (giftModel.getGift_bag() == 10) {
|
||||
helper.setText(R.id.tv_gift_name,"");
|
||||
helper.getView(R.id.cl_gift).setBackgroundResource(R.mipmap.gift_tkzj);
|
||||
helper.getView(R.id.tv_gift_name).setBackgroundResource(R.mipmap.gift_name_tkzj);
|
||||
} else if (giftModel.getGift_bag() == 11) {
|
||||
helper.setText(R.id.tv_gift_name,"");
|
||||
helper.getView(R.id.cl_gift).setBackgroundResource(R.mipmap.gift_syzc);
|
||||
helper.getView(R.id.tv_gift_name).setBackgroundResource(R.mipmap.gift_name_syzc);
|
||||
} else if (giftModel.getGift_bag() == 12) {
|
||||
helper.setText(R.id.tv_gift_name,"");
|
||||
helper.getView(R.id.cl_gift).setBackgroundResource(R.mipmap.gift_sjzd);
|
||||
helper.getView(R.id.tv_gift_name).setBackgroundResource(R.mipmap.gift_name_skzd);
|
||||
}else {
|
||||
helper.setText(R.id.tv_gift_name,giftModel.getGift_name());
|
||||
helper.getView(R.id.tv_gift_name).setBackgroundResource(0);
|
||||
helper.getView(R.id.cl_gift).setBackgroundResource(R.mipmap.gift_bj);
|
||||
}
|
||||
|
||||
if (giftModel.isChecked()) {//被选中
|
||||
helper.getView(R.id.cl_iv_down_on).setBackgroundResource(R.mipmap.room_gift_bjx);
|
||||
helper.setVisible(R.id.iv_down_on,false);
|
||||
} else {
|
||||
helper.getView(R.id.cl_iv_down_on).setBackgroundResource(0);
|
||||
helper.setVisible(R.id.iv_down_on,false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position + (long) curIndex * pageSize;
|
||||
return position;
|
||||
// return position + (long) curIndex * pageSize;
|
||||
}
|
||||
|
||||
private static class MyGestureDetector extends GestureDetector {
|
||||
@@ -116,124 +195,130 @@ public class GiftRoomAdapter extends BaseAdapter {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressLint({"SetTextI18n", "ClickableViewAccessibility"})
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
ViewHolder viewHolder;
|
||||
RoonGiftModel giftModel = getItem(position);
|
||||
if (convertView == null) {
|
||||
convertView = inflater.inflate(R.layout.item_gift_room, parent, false);
|
||||
viewHolder = new ViewHolder();
|
||||
viewHolder.item_layout = (ConstraintLayout) convertView.findViewById(R.id.cl_gift);
|
||||
viewHolder.cl_iv_down_on = (ConstraintLayout) convertView.findViewById(R.id.cl_iv_down_on);
|
||||
viewHolder.tv_gift_name = (TextView) convertView.findViewById(R.id.tv_gift_name);
|
||||
viewHolder.tv_gift_price = (TextView) convertView.findViewById(R.id.tv_gift_price);
|
||||
viewHolder.iv_gift_pic = (ImageView) convertView.findViewById(R.id.iv_gift_pic);
|
||||
viewHolder.ivDownOn = (ImageView) convertView.findViewById(R.id.iv_down_on);
|
||||
viewHolder.iv_gift_select = (ImageView) convertView.findViewById(R.id.iv_gift_select);
|
||||
|
||||
// im_heart现在位于顶层布局中
|
||||
viewHolder.im_heart = (ImageView) convertView.findViewById(R.id.im_heartssss);
|
||||
convertView.setTag(viewHolder);
|
||||
} else {
|
||||
viewHolder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
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(VISIBLE);
|
||||
}
|
||||
|
||||
if (giftModel.getIs_cp() == 0 && giftModel.getIs_teacher() == 0 ) {//这是cp礼物
|
||||
viewHolder.im_heart.setVisibility(GONE);
|
||||
} else {
|
||||
if (viewHolder.im_heart != null) {
|
||||
viewHolder.im_heart.setVisibility(VISIBLE);
|
||||
if (giftModel.getIs_cp() == 1) {
|
||||
viewHolder.im_heart.setImageResource(R.mipmap.icon_heart);
|
||||
}else if (giftModel.getIs_teacher() == 1) {
|
||||
viewHolder.im_heart.setImageResource(R.mipmap.icon_teacher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 在给View绑定显示的数据时,计算正确的position = position + curIndex * pageSize,
|
||||
*/
|
||||
// viewHolder.tv_gift_num.setVisibility(type.equals("1") ? View.VISIBLE : View.INVISIBLE);
|
||||
// viewHolder.tv_gift_change_love_values.setVisibility(View.GONE);
|
||||
|
||||
|
||||
//设置礼物名字
|
||||
viewHolder.tv_gift_name.setText(giftModel.getGift_name());
|
||||
//设置礼物价格
|
||||
String surplusTxt = giftModel.getGift_price();
|
||||
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(surplusTxt);
|
||||
//ForegroundColorSpan 为文字前景色,BackgroundColorSpan为文字背景色
|
||||
ForegroundColorSpan redSpan = new ForegroundColorSpan(mContext.getResources().getColor(R.color.color_FFA9A9A9));
|
||||
stringBuilder.setSpan(redSpan, surplusTxt.length(), surplusTxt.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//修改最后两个字体的颜色
|
||||
viewHolder.tv_gift_price.setText(stringBuilder);
|
||||
// viewHolder.item_layout.setTag(R.id.id_gift_tag, giftModel);
|
||||
|
||||
//加载礼物图片
|
||||
ImageUtils.loadImageView(giftModel.getBase_image(), viewHolder.iv_gift_pic);
|
||||
//设置选中后的样式
|
||||
|
||||
if (giftModel.isChecked()) {//被选中
|
||||
viewHolder.cl_iv_down_on.setBackgroundResource(R.mipmap.room_gift_bjx);
|
||||
viewHolder.ivDownOn.setVisibility(View.GONE);
|
||||
} else {
|
||||
viewHolder.ivDownOn.setVisibility(View.GONE);
|
||||
viewHolder.cl_iv_down_on.setBackgroundResource(0);
|
||||
}
|
||||
//设置
|
||||
// //设置礼物心动值
|
||||
// if (giftModel.getCardiac().equals("0")) {
|
||||
// viewHolder.tv_gift_change_love_values.setBackgroundResource(R.mipmap.room_gift_xin_dong_reduce);
|
||||
// viewHolder.tv_gift_change_love_values.setText(String.format("%s", giftModel.getCardiac()));
|
||||
// @Override
|
||||
// @SuppressLint({"SetTextI18n", "ClickableViewAccessibility"})
|
||||
// public View getView(int position, View convertView, ViewGroup parent) {
|
||||
// ViewHolder viewHolder;
|
||||
// RoonGiftModel giftModel = getItem(position);
|
||||
// if (convertView == null) {
|
||||
// convertView = inflater.inflate(R.layout.item_gift_room, parent, false);
|
||||
// viewHolder = new ViewHolder();
|
||||
// viewHolder.item_layout = (ConstraintLayout) convertView.findViewById(R.id.cl_gift);
|
||||
// viewHolder.cl_iv_down_on = (ConstraintLayout) convertView.findViewById(R.id.cl_iv_down_on);
|
||||
// viewHolder.tv_gift_name = (TextView) convertView.findViewById(R.id.tv_gift_name);
|
||||
// viewHolder.tv_gift_price = (TextView) convertView.findViewById(R.id.tv_gift_price);
|
||||
// viewHolder.iv_gift_pic = (ImageView) convertView.findViewById(R.id.iv_gift_pic);
|
||||
// viewHolder.ivDownOn = (ImageView) convertView.findViewById(R.id.iv_down_on);
|
||||
// viewHolder.iv_gift_select = (ImageView) convertView.findViewById(R.id.iv_gift_select);
|
||||
//
|
||||
// // im_heart现在位于顶层布局中
|
||||
// viewHolder.im_heart = (ImageView) convertView.findViewById(R.id.im_heartssss);
|
||||
// convertView.setTag(viewHolder);
|
||||
// } else {
|
||||
// viewHolder.tv_gift_change_love_values.setBackgroundResource(R.mipmap.room_gift_xin_dong_add);
|
||||
// viewHolder.tv_gift_change_love_values.setText(String.format("+%s", giftModel.getCardiac()));
|
||||
// viewHolder = (ViewHolder) convertView.getTag();
|
||||
// }
|
||||
// if (giftModel.isManghe()) {
|
||||
// viewHolder.tv_gift_change_love_values.setVisibility(View.GONE);
|
||||
//
|
||||
// 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(VISIBLE);
|
||||
// }
|
||||
if (giftModel.getGift_bag() == 10) {
|
||||
|
||||
viewHolder.item_layout.setBackgroundResource(R.mipmap.gift_tkzj);
|
||||
viewHolder.tv_gift_name.setText("");
|
||||
viewHolder.tv_gift_name.setBackgroundResource(R.mipmap.gift_name_tkzj);
|
||||
} else if (giftModel.getGift_bag() == 11) {
|
||||
viewHolder.tv_gift_name.setText("");
|
||||
viewHolder.item_layout.setBackgroundResource(R.mipmap.gift_syzc);
|
||||
viewHolder.tv_gift_name.setBackgroundResource(R.mipmap.gift_name_syzc);
|
||||
} else if (giftModel.getGift_bag() == 12) {
|
||||
viewHolder.tv_gift_name.setText("");
|
||||
viewHolder.item_layout.setBackgroundResource(R.mipmap.gift_sjzd);
|
||||
viewHolder.tv_gift_name.setBackgroundResource(R.mipmap.gift_name_skzd);
|
||||
}
|
||||
return convertView;
|
||||
}
|
||||
|
||||
|
||||
static class ViewHolder {
|
||||
public ConstraintLayout item_layout;
|
||||
public TextView tv_gift_name, tv_gift_price, tv_gift_num;
|
||||
public ImageView iv_gift_pic;
|
||||
public TextView tv_gift_change_love_values;
|
||||
public ImageView ivDownOn;
|
||||
public ImageView iv_gift_select;
|
||||
public ImageView im_heart;
|
||||
public ConstraintLayout cl_iv_down_on;
|
||||
}
|
||||
// if (TextUtils.isEmpty(giftModel.getIcon())) {
|
||||
// viewHolder.im_heart.setVisibility(GONE);
|
||||
// }else {
|
||||
// viewHolder.im_heart.setVisibility(VISIBLE);
|
||||
// ImageUtils.loadHead(giftModel.getIcon(), viewHolder.im_heart);
|
||||
// }
|
||||
//
|
||||
//// if (giftModel.getIs_cp() == 0 && giftModel.getIs_teacher() == 0 ) {//这是cp礼物
|
||||
//// viewHolder.im_heart.setVisibility(GONE);
|
||||
//// } else {
|
||||
//// if (viewHolder.im_heart != null) {
|
||||
//// viewHolder.im_heart.setVisibility(VISIBLE);
|
||||
//// if (giftModel.getIs_cp() == 1) {
|
||||
//// viewHolder.im_heart.setImageResource(R.mipmap.icon_heart);
|
||||
//// }else if (giftModel.getIs_teacher() == 1) {
|
||||
//// viewHolder.im_heart.setImageResource(R.mipmap.icon_teacher);
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//
|
||||
//
|
||||
// /*
|
||||
// * 在给View绑定显示的数据时,计算正确的position = position + curIndex * pageSize,
|
||||
// */
|
||||
//// viewHolder.tv_gift_num.setVisibility(type.equals("1") ? View.VISIBLE : View.INVISIBLE);
|
||||
//// viewHolder.tv_gift_change_love_values.setVisibility(View.GONE);
|
||||
//
|
||||
//
|
||||
// //设置礼物名字
|
||||
// viewHolder.tv_gift_name.setText(giftModel.getGift_name());
|
||||
// //设置礼物价格
|
||||
// String surplusTxt = giftModel.getGift_price();
|
||||
// SpannableStringBuilder stringBuilder = new SpannableStringBuilder(surplusTxt);
|
||||
// //ForegroundColorSpan 为文字前景色,BackgroundColorSpan为文字背景色
|
||||
// ForegroundColorSpan redSpan = new ForegroundColorSpan(mContext.getResources().getColor(R.color.color_FFA9A9A9));
|
||||
// stringBuilder.setSpan(redSpan, surplusTxt.length(), surplusTxt.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//修改最后两个字体的颜色
|
||||
// viewHolder.tv_gift_price.setText(stringBuilder);
|
||||
//// viewHolder.item_layout.setTag(R.id.id_gift_tag, giftModel);
|
||||
//
|
||||
// //加载礼物图片
|
||||
// ImageUtils.loadImageView(giftModel.getBase_image(), viewHolder.iv_gift_pic);
|
||||
// //设置选中后的样式
|
||||
//
|
||||
// if (giftModel.isChecked()) {//被选中
|
||||
// viewHolder.cl_iv_down_on.setBackgroundResource(R.mipmap.room_gift_bjx);
|
||||
// viewHolder.ivDownOn.setVisibility(View.GONE);
|
||||
// } else {
|
||||
// viewHolder.ivDownOn.setVisibility(View.GONE);
|
||||
// viewHolder.cl_iv_down_on.setBackgroundResource(0);
|
||||
// }
|
||||
// //设置
|
||||
//// //设置礼物心动值
|
||||
//// if (giftModel.getCardiac().equals("0")) {
|
||||
//// viewHolder.tv_gift_change_love_values.setBackgroundResource(R.mipmap.room_gift_xin_dong_reduce);
|
||||
//// viewHolder.tv_gift_change_love_values.setText(String.format("%s", giftModel.getCardiac()));
|
||||
//// } else {
|
||||
//// viewHolder.tv_gift_change_love_values.setBackgroundResource(R.mipmap.room_gift_xin_dong_add);
|
||||
//// viewHolder.tv_gift_change_love_values.setText(String.format("+%s", giftModel.getCardiac()));
|
||||
//// }
|
||||
//// if (giftModel.isManghe()) {
|
||||
//// viewHolder.tv_gift_change_love_values.setVisibility(View.GONE);
|
||||
//// }
|
||||
// if (giftModel.getGift_bag() == 10) {
|
||||
//
|
||||
// viewHolder.item_layout.setBackgroundResource(R.mipmap.gift_tkzj);
|
||||
// viewHolder.tv_gift_name.setText("");
|
||||
// viewHolder.tv_gift_name.setBackgroundResource(R.mipmap.gift_name_tkzj);
|
||||
// } else if (giftModel.getGift_bag() == 11) {
|
||||
// viewHolder.tv_gift_name.setText("");
|
||||
// viewHolder.item_layout.setBackgroundResource(R.mipmap.gift_syzc);
|
||||
// viewHolder.tv_gift_name.setBackgroundResource(R.mipmap.gift_name_syzc);
|
||||
// } else if (giftModel.getGift_bag() == 12) {
|
||||
// viewHolder.tv_gift_name.setText("");
|
||||
// viewHolder.item_layout.setBackgroundResource(R.mipmap.gift_sjzd);
|
||||
// viewHolder.tv_gift_name.setBackgroundResource(R.mipmap.gift_name_skzd);
|
||||
// }
|
||||
// return convertView;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// static class ViewHolder {
|
||||
// public ConstraintLayout item_layout;
|
||||
// public TextView tv_gift_name, tv_gift_price, tv_gift_num;
|
||||
// public ImageView iv_gift_pic;
|
||||
// public TextView tv_gift_change_love_values;
|
||||
// public ImageView ivDownOn;
|
||||
// public ImageView iv_gift_select;
|
||||
// public ImageView im_heart;
|
||||
// public ConstraintLayout cl_iv_down_on;
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public class GiftTwoDetailsFragment extends BaseMvpFragment<RewardGiftPresenter,
|
||||
}
|
||||
|
||||
public void loadDataIfNeeded(String id, int type, String roomId) {
|
||||
if (MvpPre==null){
|
||||
if (MvpPre == null) {
|
||||
MvpPre = new RewardGiftPresenter(this, getActivity());
|
||||
}
|
||||
if (id.equals("0")) {
|
||||
@@ -95,11 +95,12 @@ public class GiftTwoDetailsFragment extends BaseMvpFragment<RewardGiftPresenter,
|
||||
}
|
||||
|
||||
}
|
||||
bdgiftId = "";
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onString(GiftPackEvent event) {
|
||||
if (event!=null && event.getBdid()!=null) {
|
||||
if (event != null && event.getBdid() != null) {
|
||||
bdgiftId = event.getBdid();
|
||||
MvpPre.giftPack();
|
||||
}
|
||||
@@ -107,7 +108,7 @@ public class GiftTwoDetailsFragment extends BaseMvpFragment<RewardGiftPresenter,
|
||||
|
||||
@Override
|
||||
protected void initData() {
|
||||
if (type==0){
|
||||
if (type == 0) {//当type=0的时候,这个是点击排麦插队礼物的,这里传递的id是0
|
||||
MvpPre.getGiftList("0", type, roomId);
|
||||
}
|
||||
}
|
||||
@@ -157,6 +158,7 @@ public class GiftTwoDetailsFragment extends BaseMvpFragment<RewardGiftPresenter,
|
||||
if (pageCount > 0) {
|
||||
roomAdapter = new GiftRoomAdapter(CommonAppContext.getInstance(), data, 0, "0");
|
||||
mBinding.rvGift.setAdapter(roomAdapter);
|
||||
roomAdapter.setNewData(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,6 +225,11 @@ public class GiftTwoDetailsFragment extends BaseMvpFragment<RewardGiftPresenter,
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void roomHotCard() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getRewardList(List<RewardUserBean> rewardUserBeanList) {
|
||||
|
||||
@@ -300,7 +307,7 @@ public class GiftTwoDetailsFragment extends BaseMvpFragment<RewardGiftPresenter,
|
||||
giftModel.setChecked(true);
|
||||
roonGiftModel.setChecked(giftModel.isChecked());
|
||||
EventBus.getDefault().post(new GiftUserRefreshEvent(true, event.type, roonGiftModel));
|
||||
}else {
|
||||
} else {
|
||||
giftModel.setChecked(false);
|
||||
roonGiftModel.setChecked(giftModel.isChecked());
|
||||
}
|
||||
@@ -330,7 +337,7 @@ public class GiftTwoDetailsFragment extends BaseMvpFragment<RewardGiftPresenter,
|
||||
giftModel.setChecked(true);
|
||||
roonGiftModel.setChecked(giftModel.isChecked());
|
||||
EventBus.getDefault().post(new GiftUserRefreshEvent(true, event.type, roonGiftModel));
|
||||
}else {
|
||||
} else {
|
||||
giftModel.setChecked(false);
|
||||
roonGiftModel.setChecked(giftModel.isChecked());
|
||||
EventBus.getDefault().post(new GiftUserRefreshEvent(true, event.type, roonGiftModel));
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.xscm.moduleutil.base
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.voice.lib_base.ext.inflateBindingWithGeneric
|
||||
import com.xscm.moduleutil.R
|
||||
|
||||
|
||||
open class BaseBottomFragmentDialog<B : ViewBinding?>(private val resourceID: Int) :
|
||||
DialogFragment() {
|
||||
var mDatabind: B? = null
|
||||
val mBinding: B get() = mDatabind!!
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val dialog = Dialog(requireActivity(), R.style.myChooseDialog)
|
||||
mDatabind = DataBindingUtil.inflate(LayoutInflater.from(requireContext()), resourceID, null, false) as B
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
dialog.setContentView(mBinding!!.root)
|
||||
val window = dialog.window
|
||||
val params = window!!.attributes
|
||||
params.width = WindowManager.LayoutParams.MATCH_PARENT
|
||||
params.height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
params.gravity = Gravity.BOTTOM
|
||||
window.attributes = params
|
||||
dialog.setCanceledOnTouchOutside(true)
|
||||
return dialog
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
mDatabind = inflateBindingWithGeneric(inflater, container, false)
|
||||
// return if (mBinding != null) mBinding!!.root else mDatabind?.root
|
||||
return mBinding?.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
WindowCompat.setDecorFitsSystemWindows(requireDialog().window!!, false)
|
||||
requireDialog().setOnShowListener { dialog: DialogInterface? ->
|
||||
(view.parent as ViewGroup).setBackgroundColor(
|
||||
Color.TRANSPARENT
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
mDatabind = null
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun setBundleArgs(bundleArgs: Bundle?): BaseBottomFragmentDialog<B> {
|
||||
arguments = bundleArgs
|
||||
return this
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.xscm.moduleutil.base
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.voice.lib_base.ext.inflateBindingWithGeneric
|
||||
import com.xscm.moduleutil.R
|
||||
|
||||
open class BaseFragmentDialog<B : ViewBinding?>(private val resourceID: Int) : DialogFragment() {
|
||||
var mDatabind: B? = null
|
||||
val mBinding: B get() = mDatabind!!
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val dialog = Dialog(requireActivity(), R.style.myChooseDialog)
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
mDatabind = DataBindingUtil.inflate<ViewDataBinding>(LayoutInflater.from(requireContext()), resourceID, null, false) as B
|
||||
dialog.setContentView(mDatabind!!.root)
|
||||
val window = dialog.window
|
||||
val params = window!!.attributes
|
||||
params.width = WindowManager.LayoutParams.MATCH_PARENT
|
||||
params.height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
window.attributes = params
|
||||
dialog.setCanceledOnTouchOutside(true)
|
||||
return dialog
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
mDatabind = inflateBindingWithGeneric(inflater, container, false)
|
||||
return if (mBinding != null) mBinding!!.root else null
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
WindowCompat.setDecorFitsSystemWindows(requireDialog().window!!, false)
|
||||
requireDialog().setOnShowListener { dialog: DialogInterface? ->
|
||||
(view.parent as ViewGroup).setBackgroundColor(
|
||||
Color.TRANSPARENT
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
mDatabind = null
|
||||
}
|
||||
|
||||
|
||||
fun setBundleArgs(bundleArgs: Bundle?): BaseFragmentDialog<B> {
|
||||
arguments = bundleArgs
|
||||
return this
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.xscm.moduleutil.base
|
||||
|
||||
import androidx.lifecycle.*
|
||||
import com.xscm.moduleutil.http.RetrofitClient
|
||||
import com.xscm.moduleutil.widget.room.PassRoomException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.MultipartBody
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
open class BaseViewModel : ViewModel(), LifecycleObserver {
|
||||
private var clickTime: Long = 0
|
||||
var baseRepository = RetrofitClient.getInstance()
|
||||
|
||||
private val passRoom by lazy { MutableLiveData<Exception>() }
|
||||
|
||||
private val error by lazy { MutableLiveData<Exception>() }
|
||||
|
||||
private val finally by lazy { MutableLiveData<Int>() }
|
||||
|
||||
|
||||
|
||||
|
||||
//进入房间
|
||||
|
||||
var imgListData: MutableLiveData<List<String>> = MutableLiveData()
|
||||
var addImgData = MutableLiveData<Any>()
|
||||
|
||||
|
||||
//运行在UI线程的协程
|
||||
fun launchUI(block: suspend CoroutineScope.() -> Unit) = viewModelScope.launch {
|
||||
try {
|
||||
block()
|
||||
} catch (e: Exception) {
|
||||
if (e is PassRoomException) {
|
||||
passRoom.value = e
|
||||
} else {
|
||||
error.value = e
|
||||
// throw e
|
||||
}
|
||||
|
||||
} finally {
|
||||
finally.value = 200
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求失败,出现异常
|
||||
*/
|
||||
fun getError(): LiveData<Exception> {
|
||||
return error
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求完成,在此处做一些关闭操作
|
||||
*/
|
||||
fun getFinally(): LiveData<Int> {
|
||||
return finally
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import androidx.multidex.MultiDex;
|
||||
import androidx.multidex.MultiDexApplication;
|
||||
|
||||
import com.alibaba.android.arouter.launcher.ARouter;
|
||||
import com.blankj.utilcode.util.ActivityUtils;
|
||||
import com.blankj.utilcode.util.AppUtils;
|
||||
import com.blankj.utilcode.util.FileUtils;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
@@ -43,6 +44,7 @@ import com.tencent.qcloud.tuicore.TUILogin;
|
||||
import com.tencent.qcloud.tuicore.interfaces.TUICallback;
|
||||
import com.xscm.moduleutil.bean.UserBean;
|
||||
import com.xscm.moduleutil.bean.UserInfo;
|
||||
import com.xscm.moduleutil.dialog.ConfirmDialog;
|
||||
import com.xscm.moduleutil.event.AppLifecycleEvent;
|
||||
import com.xscm.moduleutil.event.UnreadCountEvent;
|
||||
import com.xscm.moduleutil.http.RetrofitClient;
|
||||
@@ -75,7 +77,7 @@ import lombok.Setter;
|
||||
* Created by cxf on 2017/8/3.
|
||||
*/
|
||||
|
||||
public class CommonAppContext extends MultiDexApplication implements Application.ActivityLifecycleCallbacks {
|
||||
public class CommonAppContext extends MultiDexApplication implements Application.ActivityLifecycleCallbacks {
|
||||
|
||||
private static CommonAppContext sInstance;
|
||||
private static Handler sMainThreadHandler;
|
||||
@@ -95,17 +97,19 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio
|
||||
|
||||
public boolean isShowAg;
|
||||
|
||||
public boolean isRoomJoininj=false;
|
||||
public boolean isRoomJoininj = false;
|
||||
|
||||
public String playCover;
|
||||
public boolean showSelf;//盲盒是否能送自己
|
||||
public String playName;
|
||||
private MqttConnect mqttConnect=null;
|
||||
private MqttConnect mqttConnect = null;
|
||||
|
||||
// 添加后台状态标记
|
||||
private boolean wasInBackground = false;
|
||||
|
||||
public boolean isMai=false;
|
||||
public boolean isMai = false;
|
||||
|
||||
public boolean isLogout = false;
|
||||
|
||||
public void onAppBackground() {
|
||||
wasInBackground = true;
|
||||
@@ -123,16 +127,24 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio
|
||||
|
||||
private AppStateListener appStateListener;
|
||||
private boolean isListeningUnreadCount = false;
|
||||
public boolean onConnectFailed=false;//是否重连
|
||||
public boolean onConnectFailed = false;//是否重连
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public Map<String, Integer> onlineMap=new HashMap<>();
|
||||
public Map<String, Integer> onlineMap = new HashMap<>();
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public UnreadCountEvent unreadCountEvent;
|
||||
|
||||
public static int selectRelease = 1;
|
||||
|
||||
public int is_open = 0;//主题的开关
|
||||
|
||||
public String appId = "com.qxcm.qxlive";
|
||||
public String appVersionCode = "88";
|
||||
public String appVersionName = "1.0.9.8";
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
@@ -154,14 +166,18 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio
|
||||
|
||||
CrashHandler.init(this);
|
||||
|
||||
if (SpUtil.getShelf()!=0) {
|
||||
if (SpUtil.getShelf() != 0) {
|
||||
SpUtil.setShelf(1);
|
||||
}
|
||||
|
||||
if (SpUtil.getTaskService() == 1){//当如果是正式服的时候,这里就变成可以设置成辅助服务器,当如果是测试服务的时候,就是变成了测试了,
|
||||
selectRelease = 1;
|
||||
}
|
||||
|
||||
//设置mqtt环境 false 测试环境 true 正式环境
|
||||
// ExternalResConstants.INSTANCE.setIS_MQTT_RELEASE(false);
|
||||
//设置http环境 false 测试环境 true 正式环境
|
||||
ExternalResConstants.INSTANCE.setIS_HTTP_RELEASE(true);
|
||||
ExternalResConstants.INSTANCE.setIS_HTTP_RELEASE(selectRelease);
|
||||
currentEnvironment = ExternalResConstants.INSTANCE.HTTP_PATH();
|
||||
|
||||
initialization();
|
||||
@@ -209,6 +225,58 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio
|
||||
}
|
||||
}
|
||||
|
||||
public void dialogHttp(){
|
||||
new ConfirmDialog(ActivityUtils.getTopActivity(),
|
||||
"提示",
|
||||
"当前网络环境异常,请重试",
|
||||
"确认",
|
||||
"取消",
|
||||
v -> {
|
||||
// 点击“确认”按钮时执行删除操作
|
||||
selectRelease = 3;
|
||||
initHttp();
|
||||
|
||||
},
|
||||
v -> {
|
||||
selectRelease = 3;
|
||||
initHttp();
|
||||
// 点击“取消”按钮时什么都不做
|
||||
}, false, 0).show();
|
||||
}
|
||||
|
||||
public void initHttp(){
|
||||
ExternalResConstants.INSTANCE.setIS_HTTP_RELEASE(selectRelease);
|
||||
currentEnvironment = ExternalResConstants.INSTANCE.HTTP_PATH();
|
||||
try {
|
||||
RetrofitClient.INSTANCE=null;
|
||||
RetrofitClient.getInstance();
|
||||
clearLoginInfo();
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearLoginDialog(String msg){
|
||||
new ConfirmDialog(ActivityUtils.getTopActivity(),
|
||||
"提示",
|
||||
msg,
|
||||
"",
|
||||
"确定",
|
||||
v -> {
|
||||
// 点击“确认”按钮时执行删除操作
|
||||
|
||||
},
|
||||
v -> {
|
||||
try {
|
||||
clearLoginInfo();
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// 点击“取消”按钮时什么都不做
|
||||
}, true, 4).show();
|
||||
}
|
||||
|
||||
// 更新未读消息数的方法
|
||||
private void updateUnreadMessageCount() {
|
||||
V2TIMManager.getConversationManager().getTotalUnreadMessageCount(new V2TIMValueCallback<Long>() {
|
||||
@@ -228,17 +296,19 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio
|
||||
|
||||
// 通知未读数变化的方法(可以发送广播或EventBus事件)
|
||||
private void notifyUnreadCountChanged(long unreadCount) {
|
||||
UnreadCountEvent event =unreadCountEvent;
|
||||
if (event==null){
|
||||
event=new UnreadCountEvent();
|
||||
UnreadCountEvent event = unreadCountEvent;
|
||||
if (event == null) {
|
||||
event = new UnreadCountEvent();
|
||||
}
|
||||
event.setALong(unreadCount);
|
||||
// 使用EventBus通知
|
||||
CommonAppContext.getInstance().setUnreadCountEvent(event);
|
||||
EventBus.getDefault().post(event);
|
||||
EventBus.getDefault().post(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查网络是否可用
|
||||
*
|
||||
* @return true表示网络可用,false表示网络不可用
|
||||
*/
|
||||
public boolean isNetworkAvailable() {
|
||||
@@ -749,20 +819,25 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio
|
||||
SpUtil.putToken("");
|
||||
|
||||
// piaoPingManager.unsubscribe();
|
||||
FileUtils.deleteAllInDir(getCacheDir());
|
||||
FileUtils.deleteAllInDir(getExternalCacheDir());
|
||||
// TODO: 2026/1/22 清楚本地缓存,但是在清楚的时候,会把所有的图片缓存就清除了,这是不对的,今天进行了修改,注释掉
|
||||
// FileUtils.deleteAllInDir(getCacheDir());
|
||||
// FileUtils.deleteAllInDir(getExternalCacheDir());
|
||||
AgoraManager.getInstance().destroy();
|
||||
// 每次启动应用时重置状态
|
||||
SpUtil.setBooleanValue("youth_model_shown", false);
|
||||
|
||||
if (mqttConnect != null){
|
||||
mqttConnect.close();
|
||||
mqttConnect = null;
|
||||
}
|
||||
|
||||
|
||||
isLogout = true;
|
||||
// 发送广播通知所有Activity刷新状态
|
||||
Intent refreshIntent = new Intent("com.xscm.moduleutil.ACTION_USER_LOGOUT");
|
||||
sendBroadcast(refreshIntent);
|
||||
// Intent refreshIntent = new Intent("com.xscm.moduleutil.ACTION_USER_LOGOUT");
|
||||
// sendBroadcast(refreshIntent);
|
||||
|
||||
ActivityUtils.finishAllActivities();
|
||||
|
||||
Intent intent = new Intent("com.qxcm.qxlive.LAUNCH_PAGE");
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
getApplicationContext().startActivity(intent);
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.xscm.moduleutil.utils.config.EnvironmentEnum
|
||||
|
||||
|
||||
object ExternalResConstants {
|
||||
//================================================================================MQTT======================================================================================
|
||||
//================================================================================MQTT======================================================================================
|
||||
// var IS_MQTT_RELEASE = true
|
||||
// val MQTT_PATH_DEBUG = "tcp://1.13.181.248"
|
||||
// val MQTT_PATH_RELEASE = "tcp://1.13.101.98"
|
||||
@@ -17,12 +17,15 @@ object ExternalResConstants {
|
||||
// }
|
||||
// }
|
||||
//================================================================================HTTP======================================================================================
|
||||
var IS_HTTP_RELEASE = true
|
||||
val HTTP_PATH_DEBUG:EnvironmentEnum = EnvironmentEnum.TEST
|
||||
val HTTP_PATH_RELEASE:EnvironmentEnum = EnvironmentEnum.PRODUCTION
|
||||
var IS_HTTP_RELEASE: Int = 1 //0 测试环境 1 正式环境 2 辅助环境
|
||||
val HTTP_PATH_DEBUG: EnvironmentEnum = EnvironmentEnum.TEST
|
||||
val HTTP_PATH_RELEASE: EnvironmentEnum = EnvironmentEnum.PRODUCTION
|
||||
val HTTP_AUXILIARY: EnvironmentEnum = EnvironmentEnum.Auxiliary
|
||||
fun HTTP_PATH(): EnvironmentEnum {
|
||||
return if (IS_HTTP_RELEASE) {
|
||||
return if (IS_HTTP_RELEASE == 1) {
|
||||
HTTP_PATH_RELEASE
|
||||
} else if (IS_HTTP_RELEASE == 3) {
|
||||
HTTP_AUXILIARY
|
||||
} else {
|
||||
HTTP_PATH_DEBUG
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.xscm.moduleutil.base;
|
||||
|
||||
public class RealTimeMessages<T> {
|
||||
|
||||
public T data;
|
||||
|
||||
public int code;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.xscm.moduleutil.base
|
||||
|
||||
|
||||
data class SocketBean(
|
||||
val code: Int, val data: Any
|
||||
)
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2026/1/14 18:47
|
||||
* 用途:app配置的客服用户id和name
|
||||
*/
|
||||
class AppCustomerBean {
|
||||
var user_id: String = ""
|
||||
var user_name: String = ""
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
class BeforeJoinRoomCheckBean :Serializable {
|
||||
var room_id:String? = null
|
||||
var msg:String? = null
|
||||
var code:Int = -1
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2026/1/7 19:47
|
||||
* 用途:
|
||||
*/
|
||||
class BlackRoomBean {
|
||||
|
||||
var id: Int = 0
|
||||
var p_room_id: Int = 0
|
||||
var room_id: Int = 0
|
||||
var user_id: Int = 0
|
||||
var meet_user_id: Int = 0
|
||||
var end_time: Int = 0
|
||||
var createtime: Int = 0
|
||||
var status: Int = 0
|
||||
var heart_value: String? = ""
|
||||
/* "id": 1,
|
||||
"p_room_id": 6065,
|
||||
"room_id": 6071,
|
||||
"user_id": 20142,
|
||||
"meet_user_id": 20137,
|
||||
"end_time": 1767957473,
|
||||
"createtime": 1767784373,
|
||||
"status": 1,
|
||||
"heart_value": null*/
|
||||
}
|
||||
@@ -16,6 +16,6 @@ public class BlackUserBean {
|
||||
private int sex;
|
||||
private String user_code;
|
||||
private int is_online;
|
||||
private int is_follow;
|
||||
private int is_follow;// 是否关注 0:未关注 1:已关注 2:别人关注了你,你没有关注别人,这个2只会在粉丝中使用
|
||||
private List<String> icon;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2025/12/21 11:37
|
||||
* 用途:盲盒转盘状态
|
||||
*/
|
||||
class BlindBoxStatus {
|
||||
var gift_bag_id: Int = 0
|
||||
var name: String = ""
|
||||
var status: Int = 0 //0关闭 1开启
|
||||
var status_str: String = ""
|
||||
var icon: String = ""
|
||||
|
||||
// "gift_bag_id": 11,
|
||||
// "name": "岁月之城",
|
||||
// "status": 1,
|
||||
// "status_str": "开启中",
|
||||
// "icon": null
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import java.util.ArrayList
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2026/1/4 10:22
|
||||
* 用途:装扮价格详情
|
||||
*/
|
||||
class DecorateDetailBean {
|
||||
// 用户信息(服务端返回的user_info字段)
|
||||
@SerializedName("user_info")
|
||||
var userInfo: UserInfoDecorate? = UserInfoDecorate()
|
||||
|
||||
// 装饰商品核心信息(服务端返回的decorate字段)
|
||||
@SerializedName("decorate")
|
||||
var decorate: Decorate? = null
|
||||
|
||||
/**
|
||||
* 用户信息内部类(对应服务端user_info)
|
||||
*/
|
||||
class UserInfoDecorate {
|
||||
@SerializedName("user_id")
|
||||
var userId: Int = 0
|
||||
|
||||
@SerializedName("user_coin")
|
||||
var userCoin: String = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* 装饰商品核心信息(对应服务端decorate,直接解析服务端返回数据)
|
||||
* 注意:与之前适配器的Item模型解耦,该类仅负责接收服务端数据,不承担适配器布局类型职责
|
||||
*/
|
||||
class Decorate {
|
||||
@SerializedName("title")
|
||||
var title: String = "" // 商品名称(如“粉色花头”)
|
||||
@SerializedName("price")
|
||||
var price : String =""
|
||||
@SerializedName("base_image")
|
||||
var base_image : String =""
|
||||
@SerializedName("price_list")
|
||||
var priceList: List<PriceListBean> = ArrayList() // 价格/时长列表(服务端返回数组)
|
||||
}
|
||||
|
||||
/**
|
||||
* 价格/时长明细bean(对应服务端price_list中的单个对象)
|
||||
* 可直接解析服务端返回的每个价格项数据,同时适配适配器的PriceItem模型
|
||||
*/
|
||||
class PriceListBean {
|
||||
@SerializedName("price")
|
||||
var price: String = "" // 现价
|
||||
|
||||
@SerializedName("original_price")
|
||||
var originalPrice: String = "" // 原价
|
||||
|
||||
@SerializedName("discount")
|
||||
var discount: String = "" // 折扣(如“5.0”)
|
||||
|
||||
@SerializedName("day")
|
||||
var day: Int = 0 // 有效天数
|
||||
|
||||
@SerializedName("month")
|
||||
var month: String = "" // 有效月数
|
||||
|
||||
@SerializedName("end_time")
|
||||
var endTime: String = "" // 有效期截止时间
|
||||
}
|
||||
|
||||
// ---------------------- 适配器适配相关:转换方法 + 适配器所需模型 ----------------------
|
||||
/**
|
||||
* 适配器的Item数据模型(密封类,区分单行/多选项)
|
||||
* 与服务端数据模型解耦,专门用于RecyclerView适配器布局
|
||||
*/
|
||||
sealed class DecorateAdapterItem {
|
||||
// 单行信息类型(如“商品价格”“有效期至”)
|
||||
data class SingleItem(
|
||||
val label: String, // 左侧标签文字
|
||||
val content: String // 右侧内容文字
|
||||
) : DecorateAdapterItem()
|
||||
|
||||
// 购买时长多选项类型(承载所有时长选项)
|
||||
data class MultiOptionItem(
|
||||
val options: List<PriceListBean> // 直接复用PriceListBean(已适配服务端数据)
|
||||
) : DecorateAdapterItem()
|
||||
|
||||
// type=12专用:购买次数(加减按钮)
|
||||
data class BuyCountItem(
|
||||
val initialCount: Int,
|
||||
val unitPrice: String
|
||||
) : DecorateAdapterItem()
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换方法:将服务端数据(Decorate)转换为适配器所需数据列表(List<DecorateAdapterItem>)
|
||||
* 实现服务端数据与适配器的桥接,方便适配器直接使用
|
||||
* @param defaultSelectedPos 默认选中的时长选项下标(默认0,即第一个选项)
|
||||
*/
|
||||
fun convertToAdapterData(
|
||||
decorate: Decorate?,
|
||||
defaultSelectedPos: Int = 0
|
||||
): List<DecorateAdapterItem> {
|
||||
val adapterDataList = mutableListOf<DecorateAdapterItem>()
|
||||
if (decorate == null ) {
|
||||
return adapterDataList
|
||||
}
|
||||
|
||||
if ( decorate.priceList.isEmpty()){
|
||||
// ---------- type=12:解析单个字段(无price_list),新增购买次数、商品总价 ----------
|
||||
val unitPrice = decorate.price// 直接取Decorate的singlePrice(服务端返回的单价)
|
||||
val unitPriceStr = unitPrice // 格式化单价,避免小数异常
|
||||
|
||||
|
||||
// 2. 商品单价(单行项,取decorate.singlePrice)
|
||||
adapterDataList.add(
|
||||
DecorateAdapterItem.SingleItem(
|
||||
label = "商品单价",
|
||||
content = unitPriceStr
|
||||
)
|
||||
)
|
||||
|
||||
// 3. 购买次数(type=12专用,初始数量1,传入单价用于计算总价)
|
||||
adapterDataList.add(
|
||||
DecorateAdapterItem.BuyCountItem(
|
||||
initialCount = 1,
|
||||
unitPrice = unitPrice
|
||||
)
|
||||
)
|
||||
|
||||
// 4. 商品总价(单行项,初始:单价×1)
|
||||
adapterDataList.add(
|
||||
DecorateAdapterItem.SingleItem(
|
||||
label = "商品总价",
|
||||
content = unitPriceStr // 初始总价=单价×1
|
||||
)
|
||||
)
|
||||
|
||||
}else {
|
||||
|
||||
// 安全获取默认选中项(防止下标越界)
|
||||
val selectedPos = if (defaultSelectedPos in decorate.priceList.indices) {
|
||||
defaultSelectedPos
|
||||
} else {
|
||||
0
|
||||
}
|
||||
val selectedPriceItem = decorate.priceList[selectedPos]
|
||||
|
||||
// 1. 添加“商品价格”单行项(取选中项的现价)
|
||||
adapterDataList.add(
|
||||
DecorateAdapterItem.SingleItem(
|
||||
label = "商品价格",
|
||||
content = "${selectedPriceItem.price}" // 拼接货币符号,优化展示
|
||||
)
|
||||
)
|
||||
|
||||
// 2. 添加“有效期至”单行项(取选中项的截止时间)
|
||||
adapterDataList.add(
|
||||
DecorateAdapterItem.SingleItem(
|
||||
label = "有效期至",
|
||||
content = selectedPriceItem.endTime
|
||||
)
|
||||
)
|
||||
|
||||
// 3. 添加“购买时长”多选项(承载所有价格/时长列表)
|
||||
adapterDataList.add(
|
||||
DecorateAdapterItem.MultiOptionItem(
|
||||
options = decorate.priceList
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
return adapterDataList
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2025/12/30 9:44
|
||||
* 用途:节日主题接口
|
||||
*/
|
||||
class FestivalThemeBean {
|
||||
var is_open : Int = 0 //主题开关
|
||||
var theme_name : String = "" //主题名称
|
||||
}
|
||||
@@ -41,7 +41,8 @@ public class GiftBean {
|
||||
public boolean isSameGiftFromSameSender(GiftBean other) {
|
||||
if (other == null) return false;
|
||||
return Objects.equals(gift_id, other.gift_id) &&
|
||||
Objects.equals(senderName, other.senderName);
|
||||
Objects.equals(senderName, other.senderName) &&
|
||||
Objects.equals(nickname,other.nickname);
|
||||
}
|
||||
|
||||
// 生成礼物唯一键
|
||||
|
||||
@@ -61,7 +61,8 @@ public class GiftBoxBean {
|
||||
|
||||
private int task_type_id;
|
||||
private String task_type_name;
|
||||
|
||||
private int is_lock;//锁:0 不开启锁 1 开启锁
|
||||
private int wait_reward_num;//待领取奖励数量
|
||||
@Data
|
||||
public static class DailyTasksBean {
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2026/1/23 9:59
|
||||
* 用途:礼物墙用户列表
|
||||
*/
|
||||
class GiftWallUserBean {
|
||||
var count : Int = 0
|
||||
|
||||
var users :List<GiftWallUserItemBean> = ArrayList()
|
||||
|
||||
class GiftWallUserItemBean {
|
||||
var avatar : String = ""
|
||||
var nickname : String = ""
|
||||
var user_id : String = ""
|
||||
var count : Int = 0
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2026/1/3 10:13
|
||||
* 用途:群聊实体类
|
||||
*/
|
||||
class GroupBean {
|
||||
var guild_id: String = ""
|
||||
var guild_cover: String = ""
|
||||
var is_deacon: Int = 0 //是否是群主 1:是 ,其他的不是 2:管理员 3:普通成员
|
||||
var user_list: List<GroupUserBean> = ArrayList()
|
||||
|
||||
var name: String = ""
|
||||
var notification: String = ""
|
||||
var mute_all_member : Int = 0 //是否全体禁言 1:是 0:不是
|
||||
class GroupUserBean {
|
||||
var is_online: Int = 0 //是否在线 1:在线 0:不在线
|
||||
var market_value: Int = 0 //身价
|
||||
var nickname: String = ""
|
||||
var avatar: String = ""
|
||||
var user_code: String = ""
|
||||
var user_id: Int = 0
|
||||
var createtime: String = ""
|
||||
var is_self: Int = 0 //是否是本人 1:是 0:不是
|
||||
var role: String = ""
|
||||
var role_str: String = ""
|
||||
var in_room_id: Int = 0 //是否在房间内 1:在 0:不在
|
||||
var is_mute: Int = 0 //是否被禁言 1:是 0:不是
|
||||
var group_role : Int = 0 //群角色 1:群主 2:管理员 3:普通成员
|
||||
}
|
||||
|
||||
|
||||
/*"guild_id": "f627",
|
||||
"guild_cover": "https://yusheng-1369267578.cos.ap-guangzhou.myqcloud.com/images/android_images/325ee1f528343bb09ddc086b2b83b190.jpg",
|
||||
"is_deacon": 1,
|
||||
"user_list": [
|
||||
{
|
||||
"is_online": 1,
|
||||
"market_value": 28,
|
||||
"nickname": "🥭芒的很",
|
||||
"avatar": "https://yusheng-1369267578.cos.ap-guangzhou.myqcloud.com/images/ios_images/1764941796523.jpeg",
|
||||
"user_code": "10001",
|
||||
"user_id": 21211,
|
||||
"createtime": "2025-12-31 13:20:28",
|
||||
"is_self": 0,
|
||||
"role": "Member",
|
||||
"role_str": "普通群成员",
|
||||
"in_room_id": 0
|
||||
}
|
||||
],
|
||||
"name": "美丽的眼神的家族",
|
||||
"notification": ""*/
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2026/1/3 14:07
|
||||
* 用途:群成员列表
|
||||
*/
|
||||
class GroupUserListBean {
|
||||
var page : String=""
|
||||
var limit : String=""
|
||||
var count : String=""
|
||||
var list : List<GroupBean.GroupUserBean>?= ArrayList()
|
||||
}
|
||||
@@ -20,6 +20,7 @@ public class MusicSongBean implements Serializable {
|
||||
private String duration;//播放时长
|
||||
private int sort;//
|
||||
private String user_id;
|
||||
private String user_code="";
|
||||
private String nickname;
|
||||
private String avatar;
|
||||
private String dress;
|
||||
|
||||
@@ -54,6 +54,7 @@ public class MyRoomBean {
|
||||
private String come_count; //房间进入数
|
||||
private Double today_income; //今日收益;
|
||||
private int earnings_ratio;//房间收益比例
|
||||
private String lucky_water="";//房间幸运流水
|
||||
|
||||
@Data
|
||||
static class CpRoom {
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2026/1/3 18:44
|
||||
* 用途:装扮列表
|
||||
*/
|
||||
class PersonaltyListBean {
|
||||
var did: Int =0 // 装扮id
|
||||
var title: String = "" // 装扮名称
|
||||
var type: Int = 0 // 1头像框 2坐骑 3资料展示特效 4光圈 5气泡 6个人靓号 7房间靓号 8工会靓号 100热门
|
||||
var base_image: String = "" // 展示图片
|
||||
var play_image: String = "" // 播放图像
|
||||
var price: Int = 0 // 实际价格(金币)
|
||||
var special_num: Int = 0 // 靓号
|
||||
var original_price: Int = 0 // 原价
|
||||
var discount: Double = 0.0 // 折扣
|
||||
var discount_str: String = "" // 折扣字段
|
||||
|
||||
|
||||
/* title
|
||||
装扮名称
|
||||
|
||||
type
|
||||
|
||||
|
||||
类型:1头像框 2坐骑 3资料展示特效 4光圈 5气泡 6个人靓号 7房间靓号 8工会靓号 100热门
|
||||
|
||||
base_image
|
||||
|
||||
展示图片
|
||||
|
||||
play_image
|
||||
|
||||
播放图像
|
||||
|
||||
price
|
||||
|
||||
实际价格(金币)
|
||||
|
||||
special_num
|
||||
|
||||
靓号
|
||||
|
||||
original_price
|
||||
|
||||
原价
|
||||
|
||||
discount
|
||||
|
||||
折扣
|
||||
|
||||
discount_str
|
||||
|
||||
折扣字段*/
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2026/1/6 14:25
|
||||
* 用途:
|
||||
*/
|
||||
class PitTimeRespBean {
|
||||
var time: Int = 0
|
||||
var time_str: String = ""
|
||||
/* "time": 5,
|
||||
"time_str": "5分钟"*/
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2025/12/30 18:02
|
||||
* 用途:红包配置信息接口
|
||||
*/
|
||||
class RedPacketConfig {
|
||||
var red_packet_min_amount : Int = 0 //发红包最小金额
|
||||
var red_packet_fee : Int = 0 //发红包手续费
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RevenueBean {
|
||||
private String id;
|
||||
private int id;
|
||||
private String user_id;
|
||||
private String change_type;
|
||||
private String change_type_name;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class RoomMessageEvent extends BaseEvent {
|
||||
public static class T {
|
||||
private String text;
|
||||
private String GiftNum;
|
||||
private String pit_number;//麦位
|
||||
private String pit_number;//麦位 酒吧房的情况下,这个是抱麦的number
|
||||
private String jia_jia;//坐骑
|
||||
private UserInfo FromUserInfo;//从me
|
||||
private UserInfo ToUserInfo;// 到you
|
||||
@@ -47,13 +47,13 @@ public class RoomMessageEvent extends BaseEvent {
|
||||
private List<RoomAuction.AuctionListBean> auction_list; //拍卖列表
|
||||
private long duration;//时间
|
||||
private RoomAuction.AuctionListBean recipient;//是否成功,有值的是成功的,没有值的时候,是失败的
|
||||
private int type;//拍卖者,1:上麦、2:下麦
|
||||
private int type;//拍卖者,1:上麦、2:下麦 暴币的时候,1是大奖 2:是小奖 在酒吧房的时候, 0:没有选择自定义礼物 1:选择了自定义礼物
|
||||
private String hot_value;
|
||||
private String SendRoomId;//发起者所在的房间ID
|
||||
private String AcceptRoomId;//接收者所在的房间id
|
||||
private String PkId;
|
||||
private String room_id;//当type==1的时候。这个roomId是对方的房间id
|
||||
private String user_id = "";
|
||||
private String room_id;//当type==1的时候。这个roomId是对方的房间id 当是酒吧房的时候,就是需要进入的小房间的id
|
||||
private String user_id = ""; //当是酒吧房的时候,这个值就是要进入小黑屋的房主信息
|
||||
private String pk_end_times;//pk结束时间
|
||||
private List<RoomPitBean> userCharmList;
|
||||
|
||||
@@ -114,6 +114,10 @@ public class RoomMessageEvent extends BaseEvent {
|
||||
private String status = "";
|
||||
private String from_id = "";
|
||||
|
||||
private String play_image;//暴币播放动画地址
|
||||
|
||||
private String meet_user_id="";//当是酒吧房的时候,就是被约的用户id
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
|
||||
@@ -26,6 +26,8 @@ public class RoomSearchResp {
|
||||
private int label_id;
|
||||
private String today_hot_value;
|
||||
|
||||
private String room_password;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ public class RoonGiftModel {
|
||||
private String gift_name;//礼物名称
|
||||
private String base_image;//礼物图片
|
||||
private String gift_price;//礼物价格
|
||||
private String gift_id;//礼物id
|
||||
private String gift_id="";//礼物id
|
||||
private String gift_bag_name;
|
||||
private String rule;
|
||||
private String rule_url;
|
||||
@@ -34,9 +34,18 @@ public class RoonGiftModel {
|
||||
private int activities_id;//4:盲盒 ;5:天空之境;
|
||||
private int gift_bag;//10:天空之境 11:岁月之城 12:时空之巅
|
||||
private int is_lock;//爵位礼物 0:不锁 1:锁
|
||||
private String icon="";//礼物标签图片
|
||||
|
||||
private int is_cp;//1:是 0:不是 是不是cp心动礼物
|
||||
private int is_teacher;//1:是 0:不是 是不是师徒礼物
|
||||
|
||||
|
||||
//下面是在酒吧房使用的参数
|
||||
private int id;
|
||||
private String gift_remark_name="";//用户设置的礼物内容
|
||||
|
||||
private String user_wallet_coin;//当前的钱包金币数
|
||||
|
||||
public boolean isCan_send_self() {
|
||||
if ( isManghe()) {
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.xscm.moduleutil.bean
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2025/12/16 11:35
|
||||
* 用途:任务未领取角标
|
||||
*/
|
||||
class TasksMessage {
|
||||
var num: Int=0
|
||||
var not_received_tasks_num : Int=0 //任务未领取奖励数 这是心跳中返回的参数,用于展示任务未领取角标,是在房间内展示的
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.xscm.moduleutil.bean;
|
||||
|
||||
import com.xscm.moduleutil.R;
|
||||
import com.xscm.moduleutil.base.CommonAppContext;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@@ -9,17 +12,115 @@ import lombok.Data;
|
||||
*/
|
||||
@Data
|
||||
public class ThemeBean {
|
||||
private String theme_color;//主题颜色
|
||||
private int is_open;
|
||||
private String theme_name;
|
||||
private String theme_color="#22BB79";//主题颜色
|
||||
private String file_url;//
|
||||
private String auxiliary_color;//
|
||||
private String btn_text_color;//按钮文字颜色
|
||||
private String app_bg;//app背景图
|
||||
private String home_sel;//首页选中
|
||||
private String home_nor;//首页未选中
|
||||
private String find_sel;//广场选中
|
||||
private String find_nor;//广场未选中
|
||||
private String msg_sel;//消息选中
|
||||
private String msg_nor;//消息未选中
|
||||
private String mine_sel;//我的选中
|
||||
private String mine_nor;//我的未选中
|
||||
private String btn_text_color="#3ABC6D";//按钮文字颜色
|
||||
private int app_bg;//app背景图
|
||||
private int home_sel;//首页选中
|
||||
private int home_nor;//首页未选中
|
||||
private int find_sel;//广场选中
|
||||
private int find_nor;//广场未选中
|
||||
private int msg_sel;//消息选中
|
||||
private int msg_nor;//消息未选中
|
||||
private int mine_sel;//我的选中
|
||||
private int mine_nor;//我的未选中
|
||||
|
||||
public int getIs_open() {
|
||||
CommonAppContext.getInstance().is_open = is_open;
|
||||
return is_open;
|
||||
}
|
||||
|
||||
public void setIs_open(int is_open) {
|
||||
this.is_open = is_open;
|
||||
CommonAppContext.getInstance().is_open = is_open;
|
||||
}
|
||||
|
||||
public String getTheme_color() {
|
||||
|
||||
return "#22BB79";
|
||||
}
|
||||
|
||||
public String getFile_url() {
|
||||
return file_url;
|
||||
}
|
||||
|
||||
public String getAuxiliary_color() {
|
||||
return auxiliary_color;
|
||||
}
|
||||
|
||||
public String getBtn_text_color() {
|
||||
// if (CommonAppContext.getInstance().is_open == 1){
|
||||
// return "#FF663B";
|
||||
// }
|
||||
return "#FFFFFF";
|
||||
}
|
||||
|
||||
public int getApp_bg() {
|
||||
if (CommonAppContext.getInstance().is_open == 1){
|
||||
return R.mipmap.bg_dark;
|
||||
}else {
|
||||
return R.mipmap.activity_bj;
|
||||
}
|
||||
}
|
||||
|
||||
public int getHome_sel() {
|
||||
if (CommonAppContext.getInstance().is_open == 1){
|
||||
return R.mipmap.icon_sy_select;
|
||||
}
|
||||
return R.mipmap.tab_main_media_selected;
|
||||
|
||||
}
|
||||
|
||||
public int getHome_nor() {
|
||||
if (CommonAppContext.getInstance().is_open == 1){
|
||||
return R.mipmap.icon_sy_notselect;
|
||||
}
|
||||
return R.mipmap.tab_main_media_unselected;
|
||||
|
||||
}
|
||||
|
||||
public int getFind_sel() {
|
||||
if (CommonAppContext.getInstance().is_open == 1){
|
||||
return R.mipmap.icon_dt_select;
|
||||
}
|
||||
return R.mipmap.icon_me_trend_select;
|
||||
}
|
||||
|
||||
public int getFind_nor() {
|
||||
if (CommonAppContext.getInstance().is_open == 1){
|
||||
return R.mipmap.icon_dt_notselect;
|
||||
}
|
||||
return R.mipmap.icon_me_trend_unselect;
|
||||
}
|
||||
|
||||
public int getMsg_sel() {
|
||||
if (CommonAppContext.getInstance().is_open == 1){
|
||||
return R.mipmap.icon_xx_select;
|
||||
}
|
||||
return R.mipmap.icon_news_select;
|
||||
}
|
||||
|
||||
public int getMsg_nor() {
|
||||
if (CommonAppContext.getInstance().is_open == 1){
|
||||
return R.mipmap.icon_xx_notselect;
|
||||
}
|
||||
return R.mipmap.icon_news_un_select;
|
||||
}
|
||||
|
||||
public int getMine_sel() {
|
||||
if (CommonAppContext.getInstance().is_open == 1){
|
||||
return R.mipmap.icon_wd_select;
|
||||
}
|
||||
return R.mipmap.icon_my_select;
|
||||
}
|
||||
|
||||
public int getMine_nor() {
|
||||
if (CommonAppContext.getInstance().is_open == 1){
|
||||
return R.mipmap.icon_wd_notselect;
|
||||
}
|
||||
return R.mipmap.icon_my_un_select;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +98,8 @@ public class UserInfo extends BaseEvent implements Serializable {
|
||||
|
||||
private Master master;
|
||||
private int is_online;//是否在线 : 1在线 2离线
|
||||
private int had_custom_gift;//是否显示设置了自定义礼物 0:没有 1:有
|
||||
|
||||
|
||||
@Data
|
||||
public static class Master implements Serializable {
|
||||
|
||||
@@ -11,7 +11,7 @@ public class WalletBean {
|
||||
|
||||
private String id;
|
||||
private String user_id;
|
||||
private String coin;//金币
|
||||
private String coin="0";//金币
|
||||
private String earnings;//钻石
|
||||
private String url;//灵活就业合作伙伴协议
|
||||
private String title;//状态
|
||||
|
||||
@@ -18,6 +18,10 @@ public class BlindReslutBean {
|
||||
public class ReslutList {
|
||||
private int gift_id;//中奖礼物Id
|
||||
private int count;//中奖礼物数量
|
||||
|
||||
private String gift_price = "";
|
||||
private String gift_name = "";
|
||||
private String base_image = "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,10 +11,21 @@ public class EMMessageInfo implements MultiItemEntity {
|
||||
public static final int QXRoomMessageTypeJoin = 1001;
|
||||
/// 用户退出房间
|
||||
public static final int QXRoomMessageTypeQuit = 1002;
|
||||
|
||||
//================================================================================================麦上变化=================================================================
|
||||
/// 用户上麦
|
||||
public static final int QXRoomMessageTypeUpSeat = 1003;
|
||||
/// 用户下麦
|
||||
public static final int QXRoomMessageTypeDownSeat = 1004;
|
||||
/// 拍卖者被拉上麦
|
||||
public static final int QXRoomMessageTypeAuctionIsUp = 1022;
|
||||
/// 竞拍开始,竞拍麦位发生变化
|
||||
public static final int QXRoomMessageTypeAuctionIsStart = 1024;
|
||||
/// 互娱 麦位发生变化
|
||||
public static final int QXRoomMessageTypeSeatDidChanged = 1053;
|
||||
/// 房间内换麦
|
||||
public static final int QXRoomMessageTypehm = 1039;
|
||||
//==============================================================================================end=================================================================
|
||||
/// 房间收到礼物
|
||||
public static final int QXRoomMessageTypeGift = 1005;
|
||||
/// 设置管理员
|
||||
@@ -48,12 +59,11 @@ public class EMMessageInfo implements MultiItemEntity {
|
||||
public static final int QXRoomMessageTypeRoomUpdate = 1020;
|
||||
/// 清除魅力值
|
||||
public static final int QXRoomMessageTypeRoom = 1021;
|
||||
/// 拍卖者被拉上麦
|
||||
public static final int QXRoomMessageTypeAuctionIsUp = 1022;
|
||||
|
||||
|
||||
/// 拍卖者拍卖开始
|
||||
public static final int QXRoomMessageTypeAuctionIsSelected = 1023;
|
||||
/// 竞拍开始,竞拍麦位发生变化
|
||||
public static final int QXRoomMessageTypeAuctionIsStart = 1024;
|
||||
|
||||
/// 竞拍结束
|
||||
public static final int QXRoomMessageTypeAuctionIsEnd = 1025;
|
||||
/// 主持延时
|
||||
@@ -101,8 +111,7 @@ public class EMMessageInfo implements MultiItemEntity {
|
||||
public static final int QXRoomMessageTypeRoomFriendCreateRelation = 1051;
|
||||
/// 私密小屋结束时间发生延时
|
||||
public static final int QXRoomMessageTypeCabinTimeDelay = 1052;
|
||||
/// 麦位发生变化
|
||||
public static final int QXRoomMessageTypeSeatDidChanged = 1053;
|
||||
|
||||
/// 心动值发生变化
|
||||
public static final int QXRoomMessageTypeHeartDidChanged = 1054;
|
||||
/// 小黑屋有人退出房间
|
||||
@@ -129,8 +138,7 @@ public class EMMessageInfo implements MultiItemEntity {
|
||||
//已点歌曲数量
|
||||
public static final int QXRoomMessageTypeSongerNum = 1072;
|
||||
|
||||
/// 房间内换麦
|
||||
public static final int QXRoomMessageTypehm = 1039;
|
||||
|
||||
public static final int QXRoomMessageTypeCPText = 1080;//CP特效,进入房间的特效,
|
||||
/// 签约开始
|
||||
public static final int QXRoomMessageTypeSignStartText = 1090;
|
||||
@@ -150,6 +158,20 @@ public class EMMessageInfo implements MultiItemEntity {
|
||||
|
||||
/// 被签约者提示弹窗
|
||||
public static final int QXRoomMessageTypeSignTipText = 1094;
|
||||
/// 暴币展示动画列表
|
||||
public static final int QXRoomMessageTypeSignChat = 1100;
|
||||
|
||||
/// 酒吧房撩ta推送
|
||||
public static final int QXRoomMessageTypeFlirtatious = 1200;
|
||||
/// 进入酒吧房的小黑屋
|
||||
public static final int QXRoomMessageTypeFlirtatiousRoom = 1201;
|
||||
/// 酒吧房抱麦推送
|
||||
public static final int QXRoomMessageTypeFlirtatiousRoomPush = 1202;
|
||||
/// 酒吧房设置了自定义礼物推送
|
||||
public static final int QXRoomMessageTypeFlirtatiousRoomCustom = 1203;
|
||||
|
||||
|
||||
|
||||
private RoomMessageEvent emMessage;
|
||||
|
||||
private int custom = 0;
|
||||
@@ -204,9 +226,11 @@ public class EMMessageInfo implements MultiItemEntity {
|
||||
case QXRoomMessageTypeRoomFriendPartDidChanged:
|
||||
case QXRoomMessageTypeSeatDidChanged:
|
||||
case QXRoomMessageTypehm:
|
||||
case QXRoomMessageTypeSignChat:
|
||||
return 1;
|
||||
case QXRoomMessageTypeRoomOMh:
|
||||
case QXRoomMessageTypeGift:
|
||||
case QXRoomMessageTypeFlirtatious:
|
||||
return 3;
|
||||
case 1:
|
||||
case 2:
|
||||
|
||||
@@ -19,4 +19,6 @@ public class PkRoomInfo implements Serializable {
|
||||
private String pk_part;;//2:等待开始、3:进行中、4:惩罚阶段
|
||||
private String pk_end_times;
|
||||
private int receive_pk_user_id = -2;//接受pk的用户id
|
||||
|
||||
private String close_users="";//关闭pk麦克风的用户id
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public class RoomBean implements Serializable {
|
||||
private String room_name;//房间名称
|
||||
private String room_cover;//房间封面
|
||||
private String room_intro;//房间公告
|
||||
private String type_id;//房间类型 1:点唱(pk) 2:拍卖(真爱拍小黑屋) 3/4:交友 6:小黑屋 7:互娱 8:交友 10:签约
|
||||
private String type_id;//房间类型 1:点唱(pk) 2:拍卖(真爱拍小黑屋) 3/4:交友 6:小黑屋 7:互娱 8:交友 10:签约 11:酒吧房
|
||||
private String type_name;//房间类型名称
|
||||
private String user_id;//房主id
|
||||
private String label_id;//类型id 2:ktv type:1/3/4/8
|
||||
@@ -89,6 +89,7 @@ public class RoomBean implements Serializable {
|
||||
private int queue_number;//排麦队列人数
|
||||
private HeadlineBean head_line;
|
||||
|
||||
private int sexy_coin;//酒吧房撩的金币
|
||||
|
||||
private String room_code;
|
||||
private String popularity;
|
||||
@@ -128,6 +129,11 @@ public class RoomBean implements Serializable {
|
||||
private int is_pk; //1:接收 2:不接受
|
||||
private int last_pk_room_id;//记录上次pk的房间id
|
||||
|
||||
private String start_time="";//营业时间的开始时间
|
||||
private String end_time="";//营业时间的结束时间
|
||||
|
||||
private String room_password = "";//房间密码
|
||||
|
||||
public int getSceneId() {
|
||||
if (sound_effect != null) {
|
||||
return sound_effect.getId();
|
||||
|
||||
@@ -28,6 +28,8 @@ public class RoomHourBean extends BaseEvent {
|
||||
private String label_icon;
|
||||
private int xlh_status;
|
||||
private int redpacket_status;// >0 有红包,=0 没有红包
|
||||
|
||||
private String room_password;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class RoomInfoResp implements Serializable {
|
||||
private RoomOrderDemand demand;//嘉宾需求
|
||||
private int rejoin;
|
||||
private int is_show_self;//盲盒是否送自己
|
||||
private MusicSongBean song_user_info;
|
||||
private MusicSongBean song_user_info;//ktv
|
||||
private MusicSongBean nextInfo;
|
||||
private RoomAuction room_auction;//拍卖房信息
|
||||
private RoomCpUserBean cp_user;
|
||||
|
||||
@@ -50,7 +50,6 @@ public class RoomPitBean implements Serializable ,Cloneable{
|
||||
private String dress;//麦位用户头像装扮
|
||||
private String charm;//麦位上用户在当前房间的魅力值
|
||||
|
||||
|
||||
private String room_id;
|
||||
private String voice;
|
||||
private String shutup;
|
||||
@@ -77,9 +76,10 @@ public class RoomPitBean implements Serializable ,Cloneable{
|
||||
private String nickname_color;//昵称颜色
|
||||
private String mic_cycle;//麦圈
|
||||
|
||||
|
||||
private boolean occupied;
|
||||
private boolean imageType;//是否是演唱者
|
||||
private String end_time;//倒计时结束时间 酒吧房
|
||||
private int had_custom_gift;//是否显示设置了自定义礼物 0:没有 1:有
|
||||
|
||||
public RoomPitBean clone(){
|
||||
try {
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.xscm.moduleutil.bean.room;
|
||||
|
||||
import com.chad.library.adapter.base.entity.MultiItemEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@@ -24,6 +26,8 @@ public class RoomSettingBean implements MultiItemEntity {
|
||||
public static final int QXRoomSettingTypeRoomTypeLianG = 31;
|
||||
//签约
|
||||
public static final int QXRoomSettingTypeRoomTypeSIGNCONTRACT = 32;
|
||||
//酒吧房
|
||||
public static final int QXRoomSettingTypeRoomTypePUBROOM = 36;
|
||||
|
||||
/// 常用工具
|
||||
/// 房间补贴
|
||||
@@ -57,6 +61,16 @@ public class RoomSettingBean implements MultiItemEntity {
|
||||
public static final int QXRoomSettingTypeRoomFloatingScreen = 29;//关闭飘屏
|
||||
public static final int QXRoomSettingTypeRoomFloatingRed = 30;//红包
|
||||
|
||||
public static final int QXRoomSettingTypeRoomTheCityYears = 33;//岁月之城
|
||||
public static final int QXRoomSettingTypeRoomTimeSpace = 34;//时空之巅
|
||||
public static final int QXRoomSettingTypeRoomTimeRedSound = 35;//红包声音
|
||||
|
||||
public static final int QXRoomSettingTypeRoomBusinessTime = 37;//营业时间
|
||||
public static final int QXRoomSettingTypeRoomBusinessLegend = 38;//炼仙传说
|
||||
public static final int QXRoomSettingTypeRoomBusinessLOVE = 39;//爱豆计划
|
||||
|
||||
|
||||
|
||||
public static final int ITEM_TYPE_DEFAULT = 0;
|
||||
public static final int ITEM_TYPE_WITH_ICON = 1;
|
||||
|
||||
@@ -70,7 +84,7 @@ public class RoomSettingBean implements MultiItemEntity {
|
||||
private boolean isSelected;//是否在麦位上
|
||||
private boolean status;
|
||||
private boolean select;//是否选中
|
||||
|
||||
private List<RoomSettingBean> children; // 新增子项列表
|
||||
|
||||
public RoomSettingBean(String name, String icon, String selectName, String selectIcon, int type, int read, boolean isSelected, boolean status, boolean select) {
|
||||
this.name = name;
|
||||
@@ -96,6 +110,7 @@ public class RoomSettingBean implements MultiItemEntity {
|
||||
this.itemType = ITEM_TYPE_WITH_ICON;
|
||||
}
|
||||
}
|
||||
|
||||
// public void updateItemType() {
|
||||
// switch (type) {
|
||||
// case QXRoomSettingTypeRoomSubsidy:
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.xscm.moduleutil.bean.room.refining
|
||||
|
||||
|
||||
data class BoxJiangChiBean(
|
||||
var gid: String = "",
|
||||
var gift_name: String = "",
|
||||
var gift_price: String = "",
|
||||
var base_image: String = "",
|
||||
var play_image: String = ""
|
||||
)
|
||||
|
||||
|
||||
|
||||
data class MonsterLogBean(
|
||||
val add_time: Int,
|
||||
val id: Int,
|
||||
val is_evil_wind: Int,
|
||||
val is_join: Int,
|
||||
val win_type: Int,
|
||||
val win_type_data: List<WinTypeData>,
|
||||
val join_data: List<WinTypeData>,
|
||||
|
||||
val base_image: String,
|
||||
val gift_name: String,
|
||||
val gift_price: Int,
|
||||
val num: Int,
|
||||
val type_name: String,
|
||||
)
|
||||
|
||||
|
||||
data class WinTypeData(
|
||||
val type: Int, val type_name: String,
|
||||
val num: Int
|
||||
)
|
||||
|
||||
|
||||
data class MonsterUserLogBean(
|
||||
val add_time: Int,
|
||||
val base64_nick_name: String,
|
||||
val base_image: String,
|
||||
val gift_name: String,
|
||||
val gift_price: String,
|
||||
val head_pic: String,
|
||||
val id: Int,
|
||||
val mid: Int,
|
||||
val nick_name: String,
|
||||
val num: Int,
|
||||
val type_name: String,
|
||||
val uid: Int,
|
||||
val win_type: Int
|
||||
)
|
||||
|
||||
data class MonsterInfoBean(
|
||||
val integral: String,
|
||||
val is_finsh: Int,
|
||||
val multiple_list: List<Multiple>,
|
||||
val open_monster_price: String,
|
||||
val surplus_time: Int,
|
||||
val win_number: Int
|
||||
)
|
||||
|
||||
data class Multiple(
|
||||
val id: Int,
|
||||
val multiple: Double,
|
||||
val type_name: String,
|
||||
val num: Int,
|
||||
val type: Int
|
||||
)
|
||||
|
||||
data class MonsterResultBean(
|
||||
val head_pic: String,
|
||||
val id: String,
|
||||
val integral: String,
|
||||
val nick_name: String,
|
||||
val num: Int,
|
||||
val price: Int,
|
||||
val type: String,
|
||||
val type_name: String,
|
||||
val uid: Int
|
||||
)
|
||||
|
||||
data class MonsterEndBean(
|
||||
val game_name: String,
|
||||
val gift_name: String,
|
||||
val is_finsh: Int,
|
||||
val is_push_message: Int,
|
||||
val multiple_list: List<Multiple>,
|
||||
val num: Int,
|
||||
val surplus_time: Int,
|
||||
val total_gift_price: Int,
|
||||
val win_count: Int,
|
||||
val win_number: Int,
|
||||
val win_type_name: String,
|
||||
val base_image: String
|
||||
)
|
||||
|
||||
data class OpenMonsterBean(
|
||||
val base_image: String, // 礼物图片
|
||||
val gid: Int, // 礼物id
|
||||
val gift_name: String, // 礼物名称
|
||||
val gift_price: String, // 礼物价格
|
||||
val is_win: Int,// 是否中奖 2未中奖 1中奖
|
||||
val num: Int, // 中奖数量
|
||||
val total_gift_price: Int, // 总价格
|
||||
val type_name: String, // 中奖类型
|
||||
val win_type: Int // 中奖类型
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ public class ZhuangBanShangChengBean {
|
||||
private boolean is_select = false;
|
||||
private int num ;//数量
|
||||
private String ext_value="" ;//这是使用降身卡的时候,返回的参数,对应的是降身卡的前面,类似10%
|
||||
private String price ="";//价格
|
||||
|
||||
public boolean isIs_select() {
|
||||
return is_select;
|
||||
|
||||
@@ -80,6 +80,7 @@ public class ConfirmDialog extends Dialog {
|
||||
window.setGravity(Gravity.CENTER); // 居中显示
|
||||
window.setBackgroundDrawableResource(R.drawable.bg_r16_fff); // 透明背景
|
||||
}
|
||||
setCanceledOnTouchOutside(false); // 设置点击外部不取消对话框
|
||||
}
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
@@ -15,7 +15,9 @@ import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
|
||||
import com.alibaba.android.arouter.launcher.ARouter;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.blankj.utilcode.util.ActivityUtils;
|
||||
import com.blankj.utilcode.util.ToastUtils;
|
||||
import com.xscm.moduleutil.R;
|
||||
import com.xscm.moduleutil.adapter.BalanceRechargeAdapter;
|
||||
@@ -29,6 +31,7 @@ import com.xscm.moduleutil.color.ThemeableDrawableUtils;
|
||||
import com.xscm.moduleutil.databinding.FragmentRechargeDialogBinding;
|
||||
import com.xscm.moduleutil.presenter.RechargeDialogContacts;
|
||||
import com.xscm.moduleutil.presenter.RechargeDialogPresenter;
|
||||
import com.xscm.moduleutil.utils.ARouteConstants;
|
||||
import com.xscm.moduleutil.utils.ColorManager;
|
||||
import com.xscm.moduleutil.utils.SpUtil;
|
||||
import com.xscm.moduleutil.widget.PaymentUtil;
|
||||
@@ -105,7 +108,7 @@ public class RechargeDialogFragment extends BaseMvpDialogFragment<RechargeDialog
|
||||
private void onClick(View view) {
|
||||
if (view.getId() == R.id.tv_payment) {
|
||||
if (money.equals("0")) {
|
||||
money=mBinding.etCustomAmount.getText().toString().trim();
|
||||
money = mBinding.etCustomAmount.getText().toString().trim();
|
||||
if (TextUtils.isEmpty(money)) {
|
||||
ToastUtils.showShort("请选择充值金额");
|
||||
return;
|
||||
@@ -116,16 +119,24 @@ public class RechargeDialogFragment extends BaseMvpDialogFragment<RechargeDialog
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (!mBinding.cbPrivacy.isChecked()) {
|
||||
ToastUtils.showShort("请先勾选服务条款");
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedItem == null) {
|
||||
ToastUtils.showShort("请选择支付方式");
|
||||
return;
|
||||
}
|
||||
MvpPre.appPay(SpUtil.getUserId() + "", money, coin, selectedItem.getType(),type_params,gift_bag_id);
|
||||
MvpPre.appPay(SpUtil.getUserId() + "", money, coin, selectedItem.getType(), type_params, gift_bag_id);
|
||||
} else if (view.getId() == R.id.tv_czxy) {//充值协议
|
||||
ARouter.getInstance().build(ARouteConstants.H5).withString("url", CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl()+"/api/Page/page_show?id=37").withString("title", "充值协议").navigation();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void initView() {
|
||||
mBinding.tvPayment.setOnClickListener(this::onClick);
|
||||
mBinding.tvCzxy.setOnClickListener(this::onClick);
|
||||
mBinding.recycleView1.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
|
||||
bindTypeAdapter = new PayMethodAdapter(R.layout.item_bind_type);
|
||||
mBinding.recycleView1.setAdapter(bindTypeAdapter);
|
||||
|
||||
@@ -45,13 +45,13 @@ public class GiftLotteryAdapter extends BaseQuickAdapter<GiftBean, BaseViewHolde
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, GiftBean item) {
|
||||
helper.setText(R.id.tv_gift_time, item.getCreatetime());
|
||||
ImageUtils.loadHeadCC(item.getBase_image(),helper.getView(R.id.iv_gift_image));
|
||||
ImageUtils.loadHeadCC(item.getBase_image(), helper.getView(R.id.iv_gift_image));
|
||||
// 使用 SpannableString 给 "x4" 设置不同颜色
|
||||
TextView giftNameTextView = helper.getView(R.id.gift_name);
|
||||
TextView nickNameTextView = helper.getView(R.id.tv_user_name);
|
||||
if (giftNameTextView != null) {
|
||||
String baseName = item.getGift_name();
|
||||
String countText = "x"+item.getCount();
|
||||
String countText = "x" + item.getCount();
|
||||
String fullText = baseName + countText;
|
||||
|
||||
SpannableStringBuilder spannable = new SpannableStringBuilder(fullText);
|
||||
@@ -67,7 +67,7 @@ public class GiftLotteryAdapter extends BaseQuickAdapter<GiftBean, BaseViewHolde
|
||||
giftNameTextView.setText(spannable);
|
||||
}
|
||||
|
||||
if (nickNameTextView!=null){
|
||||
if (nickNameTextView != null && item.getNickname() != null) {
|
||||
nickNameTextView.setText(item.getNickname());
|
||||
String nickName = "赠予";
|
||||
String fullText = nickName + " " + item.getNickname();
|
||||
|
||||
@@ -115,6 +115,9 @@ public class GiftLotteryDialogFragment extends BaseMvpDialogFragment<GiftLottery
|
||||
}else if (giftBagId.equals("12")){
|
||||
mBinding.clRoot.setBackgroundResource(R.mipmap.skzj);
|
||||
mBinding.imJc.setImageResource(R.mipmap.skzl_jl);
|
||||
}else if (giftBagId.equals("61")){
|
||||
mBinding.clRoot.setBackgroundResource(R.mipmap.icon_love_record_bg);
|
||||
mBinding.imJc.setImageResource(R.mipmap.skzl_jl);
|
||||
}
|
||||
|
||||
mBinding.smartRefreshLayout.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() {
|
||||
|
||||
@@ -103,15 +103,15 @@ import java.util.List;
|
||||
// 初始化Fragment列表
|
||||
private void initFragments() {
|
||||
fragmentList = new ArrayList<>();
|
||||
fragmentList.add(new LotteryFragment().newInstance(roomId,1)); // 第1页:抽奖榜单
|
||||
fragmentList.add(new LuckyFragment().newInstance(roomId,2)); // 第1页:抽奖榜单
|
||||
// fragmentList.add(new LotteryFragment().newInstance(roomId,1)); // 第1页:抽奖榜单
|
||||
|
||||
}
|
||||
|
||||
// 初始化ViewPager
|
||||
private void initViewPager() {
|
||||
titleList.add("");
|
||||
titleList.add("");
|
||||
// titleList.add("");
|
||||
FragmentManager childFragmentManager = getChildFragmentManager();
|
||||
pagerAdapter = new MyPagerAdapter(childFragmentManager, fragmentList,titleList );
|
||||
mBinding.ivViewPager.setAdapter(pagerAdapter);
|
||||
|
||||
@@ -81,6 +81,9 @@ public class PrizePoolDialog extends BaseDialog<DialogPrizePoolBinding> {
|
||||
}else if (type == 13){
|
||||
mBinding.clPrize.setBackgroundResource(R.mipmap.xlh);
|
||||
mBinding.imJc.setImageResource(R.mipmap.xlh_jc);
|
||||
}else if (type == 38){
|
||||
mBinding.clPrize.setBackgroundResource(R.mipmap.icon_love_record_bg);
|
||||
mBinding.imJc.setImageResource(R.mipmap.xlh_jc);
|
||||
}
|
||||
|
||||
// 根据屏幕密度调整行数和列数
|
||||
|
||||
@@ -72,7 +72,8 @@ public class XlhObtainDialog extends BaseDialog<DialogXlhObtainBinding> {
|
||||
|
||||
mBinding.ivAgain.setOnClickListener(v -> {
|
||||
if (mListener != null) {
|
||||
mListener.onPlayAgainClick();
|
||||
// mListener.onPlayAgainClick();
|
||||
mListener.onCloseClick();
|
||||
}
|
||||
dismiss();
|
||||
});
|
||||
|
||||
@@ -27,6 +27,15 @@ public enum QXRoomSeatViewType {
|
||||
*/
|
||||
SIGNCONTRACT(10,"签约"),
|
||||
|
||||
|
||||
/**
|
||||
* 酒吧
|
||||
*/
|
||||
PUB(11,"酒吧"),
|
||||
/**
|
||||
* 酒吧
|
||||
*/
|
||||
PRIVATE(12,"酒吧交友小屋"),
|
||||
/**
|
||||
* 小黑屋麦位
|
||||
*/
|
||||
|
||||
@@ -15,6 +15,8 @@ enum class RoomType(
|
||||
DATING("交友", 1,3, 4, 8), // 1、3、4、8 均对应交友
|
||||
BLACK_ROOM("小黑屋", 6),
|
||||
JUKEBOX("点唱", 9),
|
||||
PUB_ROOM("酒吧", 11),
|
||||
PRIVATE_ROOM("酒吧交友小屋", 12),
|
||||
MUTUAL_ENTERTAINMENT("互娱", 7),
|
||||
SIGN_CONTRACT("签约", 10);
|
||||
|
||||
|
||||
@@ -6,6 +6,11 @@ import com.xscm.moduleutil.bean.blindboxwheel.BlindBoxBean;
|
||||
import com.xscm.moduleutil.bean.blindboxwheel.BlindReslutBean;
|
||||
import com.xscm.moduleutil.bean.blindboxwheel.XlhDrawBean;
|
||||
import com.xscm.moduleutil.bean.room.*;
|
||||
import com.xscm.moduleutil.bean.room.refining.BoxJiangChiBean;
|
||||
import com.xscm.moduleutil.bean.room.refining.MonsterInfoBean;
|
||||
import com.xscm.moduleutil.bean.room.refining.MonsterLogBean;
|
||||
import com.xscm.moduleutil.bean.room.refining.MonsterResultBean;
|
||||
import com.xscm.moduleutil.bean.room.refining.MonsterUserLogBean;
|
||||
import com.xscm.moduleutil.bean.zhuangb.ZhuangBanShangChengBean;
|
||||
import com.xscm.moduleutil.utils.cos.TempKeyBean;
|
||||
import com.xscm.moduleutil.widget.Constants;
|
||||
@@ -26,7 +31,7 @@ public interface ApiServer {
|
||||
|
||||
@FormUrlEncoded //请求验证码
|
||||
@POST(Constants.SEND_CODE)
|
||||
Observable<BaseModel<Object>> sendCode(@Field("mobile") String mobile, @Field("event") String event);
|
||||
Call<BaseModel<String>> sendCode(@Field("mobile") String mobile, @Field("event") String event);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.LOGIN)
|
||||
@@ -38,8 +43,21 @@ public interface ApiServer {
|
||||
|
||||
@FormUrlEncoded //手机换绑
|
||||
@POST(Constants.MODIFY_MOBILE)
|
||||
Call<BaseModel<String>> mobileView(@Field("mobile") String mobile, @Field("new_mobile") String new_mobile, @Field("sms_code") String sms_code);
|
||||
Call<BaseModel<String>> mobileView(@Field("mobile") String mobile, @Field("new_mobile") String new_mobile, @Field("sms_code") String sms_code,@Field("new_sms_code") String new_sms_code);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_GIFT_WALL_USER_LIST) //礼物墙礼物用户列表
|
||||
Call<BaseModel<GiftWallUserBean>> giftWallUserList( @Field("user_id") String user_id,@Field("gift_id")String gift_id,@Field("page") int page);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.SET_PIT_TIME)
|
||||
Call<BaseModel<String>> setPitTime(@Field("room_id") String roomId, @Field("time") String time);
|
||||
|
||||
@GET(Constants.GET_FESTIVAL_THEME)
|
||||
Call<BaseModel<FestivalThemeBean>> getFestivalThemeBean();
|
||||
|
||||
@GET(Constants.GET_PERSONALTY_LIST_BEAN)
|
||||
Call<BaseModel<List<PersonaltyListBean>>> getPersonaltyListBean(@Query("type") String type);
|
||||
@GET(Constants.GET_EMOTION)
|
||||
Call<BaseModel<List<Emotion>>> upEmotion();
|
||||
|
||||
@@ -106,7 +124,7 @@ public interface ApiServer {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_LOG_LIST)
|
||||
Call<BaseModel<List<RevenueBean>>> getRevenueData(@Field("page") String page, @Field("page_limit") String page_limit, @Field("in_out_type") String in_out_type, @Field("start_time") String start_time, @Field("end_time") String end_time, @Field("gift_type") String gift_type);
|
||||
Call<BaseModel<List<RevenueBean>>> getRevenueData(@Field("last_id") int page, @Field("page_limit") String page_limit, @Field("in_out_type") String in_out_type, @Field("start_time") String start_time, @Field("end_time") String end_time, @Field("gift_type") String gift_type);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_WEALTH_RANKING)
|
||||
@@ -129,6 +147,16 @@ public interface ApiServer {
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_INVITE)
|
||||
Call<BaseModel<String>> postInvite(@Field("apply_id") String apply_id, @Field("type") String type);
|
||||
@GET(Constants.GET_GROUP_INFO)
|
||||
Call<BaseModel<GroupBean>> getGuildInfo(@Query("guild_id")String guild_id);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_GROUP_INFO)
|
||||
Call<BaseModel<String>> setGuildInfo(@Field("guild_id") String guild_id, @Field("name") String guild_name, @Field("notice") String guild_notice,@Field("avatar") String guild_avatar);
|
||||
|
||||
@GET(Constants.GET_MEMBER_LIST)
|
||||
Call<BaseModel<GroupUserListBean>> memberList(@Query("page")String page, @Query("page_limit") String page_limit, @Query("guild_id") String guild_id,@Query("search") String search);
|
||||
|
||||
|
||||
@GET(Constants.GET_TEMP_KEY)
|
||||
Call<BaseModel<TempKeyBean>> getTempKey();
|
||||
@@ -254,7 +282,8 @@ public interface ApiServer {
|
||||
@POST(Constants.URL_LOGIN)
|
||||
Call<BaseModel<List<UserBean>>> oauthLogin(@Field("login_token") String login_token);
|
||||
|
||||
@GET(Constants.GET_THEME_DATA)
|
||||
// @GET(Constants.GET_THEME_DATA)
|
||||
@GET(Constants.GET_FESTIVAL_THEME)
|
||||
Call<BaseModel<ThemeBean>> getThemeData();
|
||||
|
||||
@FormUrlEncoded
|
||||
@@ -324,19 +353,28 @@ public interface ApiServer {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.CHECK_TXT)
|
||||
Call<ResponseBody> checkTxt(@Field("room_name") String room_name, @Field("room_cover") String room_cover, @Field("room_intro") String room_intro);
|
||||
Call<ResponseBody> checkTxt(@Field("room_name") String room_name, @Field("room_cover") String room_cover, @Field("room_intro") String room_intro,@Field("room_password") String room_password);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.GET_REWARD_LIST)
|
||||
Call<BaseModel<List<RewardUserBean>>> getRewardList(@Field("id") String id, @Field("page") String page, @Field("page_limit") String page_limit);
|
||||
|
||||
@GET(Constants.GET_GIFT_LABEL)
|
||||
Call<BaseModel<List<GiftLabelBean>>> getGiftLabel(@Query("have_hot") String have_hot);
|
||||
Call<BaseModel<List<GiftLabelBean>>> getGiftLabel(@Query("type") String type);
|
||||
|
||||
//获取礼物列表
|
||||
@GET(Constants.GIFT_LIST)
|
||||
Call<BaseModel<List<RoonGiftModel>>> getGiftList(@Query("label") int label, @Query("room_id") String room_id);
|
||||
|
||||
@GET(Constants.GET_CUSTOM_GIFT_LIST)
|
||||
Call<BaseModel<List<RoonGiftModel>>> getCustomGiftList(@Query("user_id") String user_id);
|
||||
|
||||
@GET(Constants.GET_NEW_GIFT_LIST) //拍卖位选择拍卖礼物,type=3 label =99
|
||||
Call<BaseModel<List<RoonGiftModel>>> getNewGiftList(@Query("label") int label, @Query("type") String type );
|
||||
|
||||
@GET(Constants.SET_CUSTOM_GIFT)
|
||||
Call<BaseModel<String>> setCustomGift(@Query("gift_id") String gift_id, @Query("gift_remark_name") String new_gift_name ,@Query("room_id") String room_id );
|
||||
|
||||
@GET(Constants.TOPIC_LIST)
|
||||
//获取话题
|
||||
Call<BaseModel<List<HeatedBean>>> topicList(@Query("page") String page, @Query("page_limit") String page_limit);
|
||||
@@ -420,6 +458,17 @@ public interface ApiServer {
|
||||
@GET(Constants.GET_MY_INFO)
|
||||
Call<BaseModel<UserInfo>> getMyInfo();
|
||||
|
||||
@GET(Constants.GET_APP_CUSTOMER_SERVICE)
|
||||
Call<BaseModel<AppCustomerBean>> appCustomerService();
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_DEL_SONG)
|
||||
Call<BaseModel<String>> delSong(@Field("room_id") String room_id, @Field("did") String did);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_SEARCH_USER)
|
||||
Call<BaseModel<List<MusicSongBean>>> searchSong(@Field("room_id") String room_id, @Field("search_user") String search_user);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.ED_USER_INFO)
|
||||
Call<BaseModel<String>> editUserInfo(@Field("nickname") String nickname, @Field("birthday") String birthday, @Field("sex") String sex, @Field("avatar") String avatar, @Field("images") String images, @Field("profile") String profile, @Field("tag_id") String tag_id);
|
||||
@@ -439,8 +488,8 @@ public interface ApiServer {
|
||||
@POST(Constants.GET_ALBUM_DETAIL)
|
||||
Call<BaseModel<AlbumBean>> getAlbumDetail(@Field("album_id") String albumId, @Field("pwd") String pwd, @Field("page") String page, @Field("page_limit") String page_limit);
|
||||
|
||||
@GET(Constants.GET_PERSONALTY)
|
||||
Call<BaseModel<List<PersonaltyBean>>> getPersonaltyList();
|
||||
@GET(Constants.GET_PERSONALTY) // from 来源: 1:道具商城 2:个性装扮
|
||||
Call<BaseModel<List<PersonaltyBean>>> getPersonaltyList(@Query("from")String frome);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.GET_SUBSIDY)
|
||||
@@ -449,6 +498,17 @@ public interface ApiServer {
|
||||
@GET(Constants.GET_DECORATE)
|
||||
Call<BaseModel<List<ZhuangBanShangChengBean>>> getDecorateList(@Query("type") String type);
|
||||
|
||||
@GET(Constants.GET_DECORATE_DETAIL)
|
||||
Call<BaseModel<DecorateDetailBean>> getDecorateDetail(@Query("did") String id);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_PAY_DECORATE)
|
||||
Call<BaseModel<String>> payDecorate(@Field("did") String id, @Field("day") String day,@Field("num") String num);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_BLACK_ROOM_LIST)
|
||||
Call<BaseModel<List<BlackRoomBean>>>getBlackRoomList(@Field("room_id") String roomId);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_GZ)
|
||||
Call<BaseModel<String>> userGuanz(@Field("user_id") String userId, @Field("type") String type);
|
||||
@@ -477,10 +537,33 @@ public interface ApiServer {
|
||||
@POST(Constants.postRoomSwToken)
|
||||
Call<BaseModel<PkSwTokenBean>> postRoomSwToken(@Field("room_id") String roomId);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_CLOSE_PK_MIC)
|
||||
Call<BaseModel<String>> closePkMic(@Field("pk_id") String pk_id,@Field("type") String type,@Field("user_id") String user_id);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.SET_USER_DECORATE)
|
||||
Call<BaseModel<String>> setUserDecorate(@Field("udid") String udid);
|
||||
|
||||
@GET(Constants.GET_MONSTER_INFO_BOX)
|
||||
Call<BaseModel<MonsterInfoBean>> get_monster_info_box();
|
||||
|
||||
@GET(Constants.GET_OPEN_BEAT_MONSTER)
|
||||
Call<BaseModel<MonsterResultBean>> open_beat_monster(@Query("rid")String rid,@Query("type") String type,@Query("num") String num);
|
||||
|
||||
@GET(Constants.GET_MONSTER_BOX_LIST)
|
||||
Call<BaseModel<List<BoxJiangChiBean>>> get_monster_box_list();
|
||||
|
||||
@GET(Constants.GET_USER_MONSTER_LOG)
|
||||
Call<BaseModel<List<MonsterUserLogBean>>> get_user_monster_log(@Query("page")String page);
|
||||
|
||||
@GET(Constants.GET_MONSTER_LOG)
|
||||
Call<BaseModel<List<MonsterLogBean>>> get_monster_log(@Query("page")String page,@Query("page_limit")String page_limit);
|
||||
|
||||
@GET(Constants.GET_MONSTER_NOTE)
|
||||
Call<BaseModel<String>> get_monster_note();
|
||||
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_CANCEL_USER_DECORATE)
|
||||
Call<BaseModel<String>> cancelUserDecorate(@Field("type") String type);
|
||||
@@ -496,12 +579,18 @@ public interface ApiServer {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.JOIN_ROOM)
|
||||
Call<BaseModel<RoomInfoResp>> roomGetIn(@Field("room_id") String roomId, @Field("password") String password);
|
||||
Call<BaseModel<RoomInfoResp>> roomGetIn(@Field("room_id") String roomId, @Field("room_password") String password);
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.BEFORE_JOIN_ROOM_CHECK)
|
||||
Call<BaseModel<BeforeJoinRoomCheckBean>> beforeJoinRoomCheck(@Field("room_id") String roomId);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.TASK_JUMP_ROOM)
|
||||
Call<BaseModel<String>> taskJumpRoomId(@Field("task_id") String taskId);
|
||||
|
||||
@GET(Constants.GET_PIT_TIME)
|
||||
Call<BaseModel<List<PitTimeRespBean>>> getPitTimeList();
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.DELETE_ALBUM_IMAGE)
|
||||
Call<BaseModel<String>> deleteAlbumImage(@Field("id") String id);
|
||||
@@ -532,7 +621,7 @@ public interface ApiServer {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.GET_ROOM_GIFT)
|
||||
Call<BaseModel<RoomGiftData>> roomGift(@Field("room_id") String room_id, @Field("gift_id") String gift_id, @Field("gift_num") String num, @Field("to_uid") String to_uid, @Field("type") String gift_type, @Field("pit_number") String pit_number, @Field("heart_id") String heat_id);
|
||||
Call<BaseModel<RoomGiftData>> roomGift(@Field("room_id") String room_id, @Field("gift_id") String gift_id, @Field("gift_num") String num, @Field("to_uid") String to_uid, @Field("type") String gift_type, @Field("pit_number") String pit_number, @Field("heart_id") String heat_id,@Field("gift_bag_id")String gift_bag_id);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_CP_GIVE_GIFT)
|
||||
@@ -556,6 +645,12 @@ public interface ApiServer {
|
||||
@GET(Constants.GET_WALLET)
|
||||
Call<BaseModel<WalletBean>> wallet();
|
||||
|
||||
@GET(Constants.GET_TASKS_MESSAGE)
|
||||
Call<BaseModel<TasksMessage>> getTasksMessage();
|
||||
|
||||
@GET(Constants.GET_REDPACKET_CONFIG)
|
||||
Call<BaseModel<RedPacketConfig>> getRedpacketConfig();
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.REDPACKET_CREATE)
|
||||
Call<ResponseBody> redPacketCreate(@Field("type") int type, @Field("password") String password, @Field("coin_type") int coin_type, @Field("total_amount") String total_amount,
|
||||
@@ -609,7 +704,11 @@ public interface ApiServer {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.APPLY_PIT)
|
||||
Call<BaseModel<String>> applyPit(@Field("room_id") String room_id, @Field("pit_number") String pit_number);
|
||||
Call<BaseModel<String>> applyPit(@Field("room_id") String room_id, @Field("pit_number") String pit_number,@Field("gift_id")String gift_id);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_LIAO_TA)
|
||||
Call<BaseModel<String>> liaoTa(@Field("room_id") String room_id, @Field("to_user_id") String user_id,@Field("type")String type);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.START_FRIEND)
|
||||
@@ -629,7 +728,7 @@ public interface ApiServer {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_KEEP_XINTIAO)
|
||||
Call<ResponseBody> keepXintiao(@Field("room_id") String room_id);
|
||||
Call<BaseModel<TasksMessage>> keepXintiao(@Field("room_id") String room_id);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.DOWN_PIT)
|
||||
@@ -679,6 +778,13 @@ public interface ApiServer {
|
||||
@POST(Constants.POST_AGREE_SONG)
|
||||
Call<BaseModel<String>> agreeSong(@Field("room_id") String roomId, @Field("type") String type);
|
||||
|
||||
@GET(Constants.GET_BLIND_BOX_STATUS)
|
||||
Call<BaseModel<List<BlindBoxStatus>>> blindBoxStatus();
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.SET_ROOM_BUSINESS_TIME)
|
||||
Call<BaseModel<String>> setRoomBusinessTime(@Field("room_id") String roomId,@Field("start_time") String startTime,@Field("end_time") String endTime);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_END_SONG)
|
||||
Call<BaseModel<String>> endSong(@Field("room_id") String roomId);
|
||||
@@ -689,7 +795,7 @@ public interface ApiServer {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.CHANGE_SONG)
|
||||
Call<BaseModel<String>> changeSong(@Field("room_id") String roomId, @Field("now_did") String now_did);
|
||||
Call<BaseModel<String>> changeSong(@Field("room_id") String roomId, @Field("now_did") String now_did,@Field("is_auto_next") String is_auto_next);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_HOST_LIST)
|
||||
@@ -700,7 +806,7 @@ public interface ApiServer {
|
||||
Call<BaseModel<List<RoomCharmRankBean>>> getCharmRank(@Field("room_id") String roomId);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_ROOM_RELATION_LIST)
|
||||
@POST(Constants.POST_ROOM_RELATION_LIST) //1:真爱拍 2:亲密拍 3:星球(互娱)
|
||||
Call<BaseModel<List<RoomRelationBean>>> roomRelationList(@Field("type") String type);
|
||||
|
||||
@FormUrlEncoded
|
||||
@@ -766,7 +872,7 @@ public interface ApiServer {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_EDIT_ROOM)
|
||||
Call<BaseModel<String>> editRoom(@Field("room_id") String room_id, @Field("room_name") String room_name, @Field("room_cover") String room_cover, @Field("room_intro") String room_intro, @Field("room_background") String room_background);
|
||||
Call<BaseModel<String>> editRoom(@Field("room_id") String room_id, @Field("room_name") String room_name, @Field("room_cover") String room_cover, @Field("room_intro") String room_intro, @Field("room_background") String room_background,@Field("room_password")String room_password);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_KICK_OUT_ROOM)
|
||||
@@ -803,7 +909,7 @@ public interface ApiServer {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_ROOM_AUCTION_JOIN)
|
||||
Call<BaseModel<RoomAuction.AuctionListBean>> roomAuctionJoin(@Field("auction_id") String auction_id, @Field("user_id") String user_id, @Field("gift_id") String gift_id, @Field("num") String num, @Field("type") String type);
|
||||
Call<BaseModel<RoomAuction.AuctionListBean>> roomAuctionJoin(@Field("auction_id") String auction_id, @Field("user_id") String user_id, @Field("gift_id") String gift_id, @Field("num") String num, @Field("type") String type,@Field("gift_bag_id") String gift_bag_id);
|
||||
|
||||
|
||||
@FormUrlEncoded
|
||||
@@ -868,6 +974,17 @@ public interface ApiServer {
|
||||
@GET(Constants.GET_GIFT_PACK_LIST_COUNT)
|
||||
Call<BaseModel<GiftPackListCount>> getGiftPackListCount();
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_ROOM_HOT_CARD)
|
||||
Call<BaseModel<String>> roomHotCard(@Field("udid") String udid, @Field("room_id") String room_id, @Field("num") String num);
|
||||
|
||||
@GET(Constants.GET_GIFT_INFO_TA)
|
||||
Call<BaseModel<RoonGiftModel>> getGiftInfoTa(@Query("room_id") String roomId, @Query("to_user_id") String user_id);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_MEETING_TA)
|
||||
Call<BaseModel<String>> meetingTa(@Field("room_id") String room_id, @Field("user_id") String user_id, @Field("gift_id") String gift_id);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.ROOM_USER_RECONNECT)
|
||||
Call<BaseModel<String>> roomUserReconnect(@Field("room_id") String room_id);
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.xscm.moduleutil.http;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.http.NetworkException;
|
||||
|
||||
import com.blankj.utilcode.util.ToastUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.Response;
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2025/12/23 16:58
|
||||
* 用途:网络状态检查拦截器,会在每次请求前检查网络状态。
|
||||
*/
|
||||
public class NetworkCheckInterceptor implements Interceptor {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public NetworkCheckInterceptor(Context context) {
|
||||
this.context = context.getApplicationContext(); // 使用 Application Context 避免内存泄漏
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
// 检查网络连接状态
|
||||
if (!isNetworkAvailable()) {
|
||||
// 如果没有网络,抛出我们自定义的异常
|
||||
ToastUtils.showLong("网络连接不可用,请检查您的网络设置");
|
||||
}
|
||||
|
||||
// 如果有网络,继续执行请求
|
||||
return chain.proceed(chain.request());
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查网络是否可用
|
||||
* @return true if network is available, false otherwise.
|
||||
*/
|
||||
private boolean isNetworkAvailable() {
|
||||
ConnectivityManager connectivityManager =
|
||||
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
if (connectivityManager != null) {
|
||||
// 获取所有网络信息
|
||||
NetworkInfo[] networkInfos = connectivityManager.getAllNetworkInfo();
|
||||
if (networkInfos != null) {
|
||||
for (NetworkInfo info : networkInfos) {
|
||||
if (info.getState() == NetworkInfo.State.CONNECTED) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -91,7 +91,9 @@ public class CustomMessageParser {
|
||||
if (pitObject.has("pit_number") && !pitObject.get("pit_number").isJsonNull()) {
|
||||
pitInfo.setPit_number(String.valueOf(pitObject.get("pit_number").getAsInt()));
|
||||
}
|
||||
|
||||
if (pitObject.has("is_online") && !pitObject.get("is_online").isJsonNull()) {
|
||||
pitInfo.setIs_online(pitObject.get("is_online").getAsInt());
|
||||
}
|
||||
pitList.add(pitInfo);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.xscm.moduleutil.listener
|
||||
|
||||
interface JoinRoomErrorListener {
|
||||
fun onJoinRoomError(errorCode: Int, errorMsg: String)
|
||||
}
|
||||
@@ -0,0 +1,703 @@
|
||||
package com.xscm.moduleutil.listener;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.blankj.utilcode.util.GsonUtils;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.tencent.imsdk.v2.V2TIMAdvancedMsgListener;
|
||||
import com.tencent.imsdk.v2.V2TIMCallback;
|
||||
import com.tencent.imsdk.v2.V2TIMConversationListener;
|
||||
import com.tencent.imsdk.v2.V2TIMGroupListener;
|
||||
import com.tencent.imsdk.v2.V2TIMGroupMemberInfo;
|
||||
import com.tencent.imsdk.v2.V2TIMManager;
|
||||
import com.tencent.imsdk.v2.V2TIMMessage;
|
||||
import com.tencent.imsdk.v2.V2TIMSendCallback;
|
||||
import com.tencent.imsdk.v2.V2TIMSimpleMsgListener;
|
||||
import com.tencent.imsdk.v2.V2TIMUserInfo;
|
||||
import com.xscm.moduleutil.base.CommonAppContext;
|
||||
import com.xscm.moduleutil.bean.HeadlineBean;
|
||||
import com.xscm.moduleutil.bean.RoomMessageEvent;
|
||||
import com.xscm.moduleutil.event.UnreadCountEvent;
|
||||
import com.xscm.moduleutil.http.RetrofitClient;
|
||||
import com.xscm.moduleutil.utils.CustomMsgCode;
|
||||
import com.xscm.moduleutil.utils.SpUtil;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
/**
|
||||
* @author qx
|
||||
* @data 2025/6/17
|
||||
* @description: 接收消息
|
||||
*/
|
||||
public class MessageExListenerSingleton {
|
||||
private static boolean isInitialized = false;
|
||||
private static MessageExListenerSingleton instance;
|
||||
private List<OnMessageReceivedListener> listeners = new ArrayList<>();
|
||||
private V2TIMSimpleMsgListener simpleMsgListener;
|
||||
private V2TIMAdvancedMsgListener v2TIMAdvancedMsgListener;
|
||||
private static String mRoomId = "";
|
||||
public static String groupId;
|
||||
private V2TIMGroupListener groupListener;
|
||||
private V2TIMConversationListener conversationListener; // 需要保存引用
|
||||
|
||||
// 添加操作状态标记
|
||||
private volatile boolean isGroupOperationInProgress = false;
|
||||
private final Object groupOperationLock = new Object();
|
||||
private Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
// 添加消息缓存机制
|
||||
private static final int MAX_CACHED_MESSAGES = 20;
|
||||
private final Map<String, List<RoomMessageEvent>> cachedMessages = new ConcurrentHashMap<>();
|
||||
private final Set<String> joinedRooms = ConcurrentHashMap.newKeySet();
|
||||
|
||||
private OnMsgTaskListener onMsgTaskListener;
|
||||
|
||||
// private boolean listenersAdded = false; // 标记监听器是否已添加
|
||||
// 1. 添加新的监听器接口
|
||||
public interface PublicScreenMessageListener {
|
||||
void onPublicScreenMessageReceived(RoomMessageEvent message);
|
||||
}
|
||||
|
||||
private List<PublicScreenMessageListener> publicScreenListeners = new ArrayList<>();
|
||||
|
||||
// 添加监听器 // 替换原有的 addPublicScreenMessageListener 方法
|
||||
public void addPublicScreenMessageListener(PublicScreenMessageListener listener) {
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (publicScreenListeners) {
|
||||
if (!publicScreenListeners.contains(listener)) {
|
||||
try {
|
||||
publicScreenListeners.add(listener);
|
||||
} catch (Exception e) {
|
||||
LogUtils.e("MessageListener", "添加 PublicScreenMessageListener 失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 同时修改 removePublicScreenMessageListener 方法
|
||||
public void removePublicScreenMessageListener(PublicScreenMessageListener listener) {
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (publicScreenListeners) {
|
||||
try {
|
||||
publicScreenListeners.remove(listener);
|
||||
} catch (Exception e) {
|
||||
LogUtils.e("MessageListener", "移除 PublicScreenMessageListener 失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 修改 notify 方法以增加保护
|
||||
private void notifyPublicScreenListeners(RoomMessageEvent message) {
|
||||
synchronized (publicScreenListeners) {
|
||||
// 创建副本以避免并发修改异常
|
||||
List<PublicScreenMessageListener> listenersCopy = new ArrayList<>(publicScreenListeners);
|
||||
for (PublicScreenMessageListener listener : listenersCopy) {
|
||||
try {
|
||||
listener.onPublicScreenMessageReceived(message);
|
||||
} catch (Exception e) {
|
||||
LogUtils.e("MessageListener", "通知 PublicScreenMessageListener 失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private MessageExListenerSingleton() {
|
||||
if (!isInitialized) {
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static MessageExListenerSingleton getInstance() {
|
||||
synchronized (MessageExListenerSingleton.class) {
|
||||
if (instance == null) {
|
||||
instance = new MessageExListenerSingleton();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存消息(用于在Fragment未准备好时存储消息)
|
||||
*/
|
||||
private void cacheMessage(String roomId, RoomMessageEvent message) {
|
||||
if (TextUtils.isEmpty(roomId) || message == null) {
|
||||
return;
|
||||
}
|
||||
// 标记该房间有待处理的消息
|
||||
List<RoomMessageEvent> roomMessages = cachedMessages.computeIfAbsent(roomId, k -> new ArrayList<>());
|
||||
|
||||
// 限制每个房间的缓存消息数量
|
||||
if (roomMessages.size() >= MAX_CACHED_MESSAGES) {
|
||||
roomMessages.remove(0); // 移除最旧的消息
|
||||
}
|
||||
|
||||
roomMessages.add(message);
|
||||
LogUtils.d("MessageListener", "缓存消息: roomId=" + roomId + ", msgType=" + message.getMsgType());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取并清除指定房间的缓存消息
|
||||
*/
|
||||
public List<RoomMessageEvent> getAndClearCachedMessages(String roomId) {
|
||||
if (TextUtils.isEmpty(roomId)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<RoomMessageEvent> messages = cachedMessages.remove(roomId);
|
||||
if (messages == null) {
|
||||
messages = new ArrayList<>();
|
||||
}
|
||||
|
||||
LogUtils.d("MessageListener", "获取并清除缓存消息: roomId=" + roomId + ", count=" + messages.size());
|
||||
return messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记房间已加入
|
||||
*/
|
||||
public void markRoomJoined(String roomId) {
|
||||
if (!TextUtils.isEmpty(roomId)) {
|
||||
joinedRooms.add(roomId);
|
||||
LogUtils.d("MessageListener", "标记房间已加入: " + roomId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查房间是否已加入
|
||||
*/
|
||||
public boolean isRoomJoined(String roomId) {
|
||||
return !TextUtils.isEmpty(roomId) && joinedRooms.contains(roomId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除房间加入标记
|
||||
*/
|
||||
public void clearRoomJoined(String roomId) {
|
||||
if (!TextUtils.isEmpty(roomId)) {
|
||||
joinedRooms.remove(roomId);
|
||||
LogUtils.d("MessageListener", "清除房间加入标记: " + roomId);
|
||||
}
|
||||
}
|
||||
|
||||
// 修改 joinGroup 方法,确保先退出再加入
|
||||
public void joinGroup(String roomId) {
|
||||
if (TextUtils.isEmpty(roomId)) {
|
||||
return;
|
||||
}
|
||||
synchronized (groupOperationLock) {
|
||||
if (isGroupOperationInProgress) {
|
||||
// 如果有操作正在进行,延迟执行
|
||||
mainHandler.removeCallbacksAndMessages(null);
|
||||
mainHandler.postDelayed(() -> joinGroup(roomId), 100);
|
||||
return;
|
||||
}
|
||||
|
||||
isGroupOperationInProgress = true;
|
||||
}
|
||||
mRoomId = roomId;
|
||||
new Thread(() -> {
|
||||
try {
|
||||
// 先退出当前群组(如果需要)
|
||||
if (groupId != null && !groupId.equals(roomId)) {
|
||||
LogUtils.d("MessageListener", "开始退出群组: " + groupId + "____room:" + roomId);
|
||||
CountDownLatch quitLatch = new CountDownLatch(1);
|
||||
boolean[] quitSuccess = {false};
|
||||
|
||||
try {
|
||||
V2TIMManager.getInstance().quitGroup("room" + groupId, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
LogUtils.d("MessageListener", "退出群组成功: " + groupId + "____room:" + roomId);
|
||||
quitSuccess[0] = true;
|
||||
quitLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
LogUtils.e("MessageListener", "退出群组失败: " + groupId + "____room:" + roomId + ", code=" + code + ", desc=" + desc);
|
||||
quitSuccess[0] = false;
|
||||
quitLatch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
// 等待退出操作完成,最多等待3秒
|
||||
try {
|
||||
quitLatch.await(3, java.util.concurrent.TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtils.e("MessageListener", "退出群组异常: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 加入新群组
|
||||
LogUtils.d("MessageListener", "开始加入群组: " + roomId);
|
||||
CountDownLatch joinLatch = new CountDownLatch(1);
|
||||
boolean[] joinSuccess = {false};
|
||||
|
||||
try {
|
||||
// 确保监听器已添加
|
||||
ensureListenersAdded();
|
||||
|
||||
V2TIMManager.getInstance().joinGroup("room" + roomId, "申请加入", new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
LogUtils.d("MessageListener", "加入im群组成功: " + roomId);
|
||||
joinSuccess[0] = true;
|
||||
groupId = roomId;
|
||||
joinLatch.countDown();
|
||||
// 标记房间已加入
|
||||
markRoomJoined(roomId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
LogUtils.e("MessageListener", "加入群组失败: " + roomId + ", code=" + code + ", desc=" + desc);
|
||||
joinSuccess[0] = false;
|
||||
joinLatch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
// 等待加入操作完成,最多等待3秒
|
||||
try {
|
||||
joinLatch.await(3, java.util.concurrent.TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtils.e("MessageListener", "加入群组异常: " + e.getMessage());
|
||||
}
|
||||
|
||||
LogUtils.d("MessageListener", "群组操作完成 - 退出成功: " + (groupId == null || !groupId.equals(roomId)) + ", 加入成功: " + joinSuccess[0]);
|
||||
|
||||
} finally {
|
||||
synchronized (groupOperationLock) {
|
||||
isGroupOperationInProgress = false;
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
private void initListeners() {
|
||||
// 简单消息监听器
|
||||
if (simpleMsgListener == null) {
|
||||
simpleMsgListener = new V2TIMSimpleMsgListener() {
|
||||
@Override
|
||||
public void onRecvC2CTextMessage(String msgID, V2TIMUserInfo sender, String text) {
|
||||
LogUtils.d("C2C 文本消息 " + sender.getNickName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecvC2CCustomMessage(String msgID, V2TIMUserInfo sender, byte[] customData) {
|
||||
LogUtils.d("C2C 自定义(信令)消息 " + sender.getNickName());
|
||||
String message = new String(customData, StandardCharsets.UTF_8);
|
||||
RoomMessageEvent event = GsonUtils.fromJson(message, RoomMessageEvent.class);
|
||||
if (event.getMsgType() == 130 || event.getMsgType() == 131) {
|
||||
// EventBus.getDefault().post(event);
|
||||
RetrofitClient.getInstance().getCpListener().onReceiveMsg(event);
|
||||
} else if (event.getMsgType() == CustomMsgCode.INSTANCE.getCODE_TASK_APPRENTICE_JOIN_ROOM()) {
|
||||
if (onMsgTaskListener != null) {
|
||||
onMsgTaskListener.onMsgTask(event);
|
||||
}
|
||||
} else {
|
||||
notifyMessageReceived(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecvGroupTextMessage(String msgID, String groupID, V2TIMGroupMemberInfo sender, String text) {
|
||||
LogUtils.d("群文本消息:群组 " + groupID + " 中 " + sender.getNickName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecvGroupCustomMessage(String msgID, String groupID, V2TIMGroupMemberInfo sender, byte[] customData) {
|
||||
LogUtils.d("收到群自定义消息:群组 " + groupID + " 中 " + sender.getNickName() +",mRoomId:"+mRoomId);
|
||||
if (!groupID.equals("")) {
|
||||
if (groupID.replace("room","").equals(mRoomId)) {
|
||||
String message = new String(customData, StandardCharsets.UTF_8);
|
||||
RoomMessageEvent event = GsonUtils.fromJson(message, RoomMessageEvent.class);
|
||||
notifyMessageReceived(event);
|
||||
LogUtils.d("收到群自定义消息(信令):", message);
|
||||
}
|
||||
} else {
|
||||
String message = new String(customData, StandardCharsets.UTF_8);
|
||||
LogUtils.d("收到群自定义消息(信令):", message);
|
||||
HeadlineBean event = GsonUtils.fromJson(message, HeadlineBean.class);
|
||||
EventBus.getDefault().post(event);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 高级消息监听器
|
||||
if (v2TIMAdvancedMsgListener == null) {
|
||||
v2TIMAdvancedMsgListener = new V2TIMAdvancedMsgListener() {
|
||||
@Override
|
||||
public void onRecvNewMessage(V2TIMMessage msg) {
|
||||
super.onRecvNewMessage(msg);
|
||||
if (msg.isBroadcastMessage()) {
|
||||
// 收到了广播消息
|
||||
String message = new String(msg.getCustomElem().getData(), StandardCharsets.UTF_8);
|
||||
LogUtils.e("收到广播消息(系统):", message);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 群组监听器
|
||||
if (groupListener == null) {
|
||||
groupListener = new V2TIMGroupListener() {
|
||||
@Override
|
||||
public void onMemberEnter(String groupID, List<V2TIMGroupMemberInfo> memberList) {
|
||||
// 有新成员加入群,该群所有的成员都能收到
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMemberLeave(String groupID, V2TIMGroupMemberInfo member) {
|
||||
// 有成员离开群,该群所有的成员都能收到
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceiveRESTCustomData(String groupID, byte[] customData) {
|
||||
String message = "";
|
||||
try {
|
||||
LogUtils.e("收到群自定义消息",groupID);
|
||||
message = new String(customData, StandardCharsets.UTF_8);
|
||||
LogUtils.e("收到群自定义消息(系统):" + message);
|
||||
} catch (Exception e) {
|
||||
// 处理转换过程中可能出现的异常,例如记录日志
|
||||
LogUtils.e("转换 customData 为 String 时出错:" + e.getMessage());
|
||||
return; // 退出方法,避免后续代码执行
|
||||
}
|
||||
|
||||
RoomMessageEvent event = null;
|
||||
try {
|
||||
// 特殊处理某些消息类型
|
||||
event = parseSpecialMessageTypes(message);
|
||||
if (event == null) {
|
||||
// 使用默认解析
|
||||
event = GsonUtils.fromJson(message, RoomMessageEvent.class);
|
||||
}
|
||||
LogUtils.e("收到群自定义消息:" + mRoomId + "===" + event);
|
||||
// event = GsonUtils.fromJson(message, RoomMessageEvent.class);
|
||||
} catch (Exception e) {
|
||||
// 处理 JSON 解析过程中可能出现的异常,例如记录日志
|
||||
LogUtils.e("解析 JSON 数据时出错:" + e.getMessage());
|
||||
return; // 退出方法,避免后续代码执行
|
||||
}
|
||||
if (groupID.contains(mRoomId)) {
|
||||
notifyMessageReceived(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 会话监听器
|
||||
if (conversationListener == null) {
|
||||
conversationListener = new V2TIMConversationListener() {
|
||||
@Override
|
||||
public void onTotalUnreadMessageCountChanged(long totalUnreadCount) {
|
||||
super.onTotalUnreadMessageCountChanged(totalUnreadCount);
|
||||
|
||||
UnreadCountEvent event = CommonAppContext.getInstance().getUnreadCountEvent();
|
||||
if (event == null) {
|
||||
event = new UnreadCountEvent();
|
||||
event.setBLong(0);
|
||||
}
|
||||
event.setALong(totalUnreadCount);
|
||||
CommonAppContext.getInstance().setUnreadCountEvent(event);
|
||||
EventBus.getDefault().post(event);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 添加所有监听器
|
||||
private void addAllListeners() {
|
||||
if (simpleMsgListener != null) {
|
||||
V2TIMManager.getInstance().addSimpleMsgListener(simpleMsgListener);
|
||||
}
|
||||
|
||||
if (v2TIMAdvancedMsgListener != null) {
|
||||
V2TIMManager.getMessageManager().addAdvancedMsgListener(v2TIMAdvancedMsgListener);
|
||||
}
|
||||
|
||||
if (groupListener != null) {
|
||||
V2TIMManager.getInstance().addGroupListener(groupListener);
|
||||
}
|
||||
|
||||
if (conversationListener != null) {
|
||||
V2TIMManager.getConversationManager().addConversationListener(conversationListener);
|
||||
}
|
||||
}
|
||||
|
||||
// 移除所有监听器
|
||||
private static void removeAllListeners() {
|
||||
if (instance != null) {
|
||||
if (instance.simpleMsgListener != null) {
|
||||
V2TIMManager.getInstance().removeSimpleMsgListener(instance.simpleMsgListener);
|
||||
}
|
||||
|
||||
if (instance.v2TIMAdvancedMsgListener != null) {
|
||||
V2TIMManager.getMessageManager().removeAdvancedMsgListener(instance.v2TIMAdvancedMsgListener);
|
||||
}
|
||||
|
||||
if (instance.groupListener != null) {
|
||||
V2TIMManager.getInstance().removeGroupListener(instance.groupListener);
|
||||
}
|
||||
|
||||
if (instance.conversationListener != null) {
|
||||
V2TIMManager.getConversationManager().removeConversationListener(instance.conversationListener);
|
||||
}
|
||||
|
||||
// instance.listenersAdded = false; // 重置标记
|
||||
}
|
||||
}
|
||||
|
||||
// 修改 quitGroup 方法
|
||||
public static void quitGroup(String mRoomId) {
|
||||
|
||||
V2TIMManager.getInstance().quitGroup("room" + mRoomId, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
LogUtils.d("@@@", "退出群组成功" + mRoomId);
|
||||
// removeAllListeners(); // 移除所有监听器
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
LogUtils.d("@@@", "退出群组失败" + mRoomId, code, desc);
|
||||
// removeAllListeners(); // 即使失败也移除监听器
|
||||
}
|
||||
});
|
||||
|
||||
if (instance != null) {
|
||||
instance.listeners.clear();
|
||||
// removeAllListeners();
|
||||
isInitialized = false;
|
||||
groupId = null;
|
||||
LogUtils.e("@@@", "重置成功");
|
||||
}
|
||||
}
|
||||
|
||||
// 修改 reset 方法
|
||||
public static void reset(String roomId) {
|
||||
if (instance != null) {
|
||||
instance.listeners.clear();
|
||||
// removeAllListeners();
|
||||
isInitialized = false;
|
||||
groupId = null;
|
||||
// instance = null;
|
||||
quitGroup(roomId);
|
||||
LogUtils.e("@@@", "重置成功");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 确保监听器已添加
|
||||
public void ensureListenersAdded() {
|
||||
initListeners();
|
||||
addAllListeners();
|
||||
}
|
||||
|
||||
|
||||
private RoomMessageEvent parseSpecialMessageTypes(String message) {
|
||||
try {
|
||||
JsonObject jsonObject = new JsonParser().parse(message).getAsJsonObject();
|
||||
int msgType = jsonObject.get("MsgType").getAsInt();
|
||||
|
||||
if (msgType == 1053) {
|
||||
return CustomMessageParser.parseMessageType1053(jsonObject);
|
||||
} else if (msgType == 1054) {
|
||||
return CustomMessageParser.parseMessageType1054(jsonObject);
|
||||
}
|
||||
|
||||
return null; // 不是特殊类型,使用默认解析
|
||||
} catch (Exception e) {
|
||||
LogUtils.e("特殊消息解析失败: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void addOnMessageReceivedListener(OnMessageReceivedListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除群组相关的监听器
|
||||
*/
|
||||
private static void removeGroupListeners() {
|
||||
if (instance != null) {
|
||||
// 移除消息监听器
|
||||
if (instance.simpleMsgListener != null) {
|
||||
V2TIMManager.getInstance().removeSimpleMsgListener(instance.simpleMsgListener);
|
||||
}
|
||||
|
||||
if (instance.v2TIMAdvancedMsgListener != null) {
|
||||
V2TIMManager.getMessageManager().removeAdvancedMsgListener(instance.v2TIMAdvancedMsgListener);
|
||||
}
|
||||
|
||||
// 移除群组监听器
|
||||
if (instance.groupListener != null) {
|
||||
V2TIMManager.getInstance().removeGroupListener(instance.groupListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendCustomRoomMessage(String roomId, byte[] binaryData) {
|
||||
|
||||
// 创建自定义群消息
|
||||
V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createCustomMessage(binaryData);
|
||||
// v2TIMMessage.setNeedReadReceipt(true);
|
||||
// 发送消息
|
||||
V2TIMManager.getMessageManager().sendMessage(
|
||||
v2TIMMessage,
|
||||
null,
|
||||
"room" + roomId,
|
||||
V2TIMMessage.V2TIM_PRIORITY_NORMAL,
|
||||
false,
|
||||
null,
|
||||
sendCallback
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: 2025/11/19 添加发送公共方法,messageType:发送的type;message:发送的内容 userId:发送给谁
|
||||
public void sendCustomC2CMessage(int messageType, String message, String userId) {
|
||||
|
||||
RoomMessageEvent.T t = new RoomMessageEvent.T();
|
||||
t.setFromUserInfo(SpUtil.getUserInfo());
|
||||
t.setText(message);
|
||||
RoomMessageEvent roomMessageEvent = new RoomMessageEvent(messageType, mRoomId, t);
|
||||
String json = GsonUtils.toJson(roomMessageEvent);
|
||||
// 转换为 byte[]
|
||||
byte[] binaryData = json.getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
// 创建自定义群消息
|
||||
V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createCustomMessage(binaryData);
|
||||
v2TIMMessage.setExcludedFromUnreadCount(true);
|
||||
v2TIMMessage.setExcludedFromContentModeration(true);
|
||||
// v2TIMMessage.setNeedReadReceipt(true);
|
||||
//
|
||||
// // 发送消息
|
||||
V2TIMManager.getMessageManager().sendMessage(v2TIMMessage, "u" + userId, null, V2TIMMessage.V2TIM_PRIORITY_HIGH,
|
||||
true,
|
||||
null,
|
||||
sendCallback);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// TODO: 2025/11/19 添加发送公共方法,messageType:发送的type;message:发送的内容 userId:发送给谁
|
||||
public void sendCustomC2CMessage(int messageType, String userId,RoomMessageEvent.T text) {
|
||||
text.setFromUserInfo(SpUtil.getUserInfo());
|
||||
LogUtils.e("发送消息", "messageType:" + messageType + "\nuserId:" + userId + "\ntext:" + text,toString());
|
||||
RoomMessageEvent roomMessageEvent = new RoomMessageEvent(messageType, mRoomId, text);
|
||||
String json = GsonUtils.toJson(roomMessageEvent);
|
||||
// 转换为 byte[]
|
||||
byte[] binaryData = json.getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
// 创建自定义群消息
|
||||
V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createCustomMessage(binaryData);
|
||||
v2TIMMessage.setExcludedFromUnreadCount(true);
|
||||
v2TIMMessage.setExcludedFromContentModeration(true);
|
||||
// v2TIMMessage.setNeedReadReceipt(true);
|
||||
//
|
||||
// // 发送消息
|
||||
V2TIMManager.getMessageManager().sendMessage(v2TIMMessage, "u" + userId, null, V2TIMMessage.V2TIM_PRIORITY_HIGH,
|
||||
true,
|
||||
null,
|
||||
sendCallback);
|
||||
|
||||
}
|
||||
|
||||
public void sendCustomC2CMessage125(String userId, byte[] binaryData) {
|
||||
// 创建自定义群消息
|
||||
V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createCustomMessage(binaryData);
|
||||
v2TIMMessage.setExcludedFromUnreadCount(true);
|
||||
v2TIMMessage.setExcludedFromContentModeration(true);
|
||||
// v2TIMMessage.setNeedReadReceipt(true);
|
||||
//
|
||||
// // 发送消息
|
||||
V2TIMManager.getMessageManager().sendMessage(v2TIMMessage, "u" + userId, null, V2TIMMessage.V2TIM_PRIORITY_HIGH,
|
||||
true,
|
||||
null,
|
||||
sendCallback);
|
||||
|
||||
}
|
||||
|
||||
// RoomFragment.java 中添加
|
||||
private final V2TIMSendCallback<V2TIMMessage> sendCallback = new V2TIMSendCallback<V2TIMMessage>() {
|
||||
@Override
|
||||
public void onProgress(int progress) {
|
||||
// 可选实现
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(V2TIMMessage message) {
|
||||
Log.d("MessageSender", "发送成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
Log.e("MessageSender", "发送失败: code=" + code + ", desc=" + desc);
|
||||
}
|
||||
};
|
||||
|
||||
private void notifyMessageReceived(RoomMessageEvent message) {
|
||||
// for (OnMessageReceivedListener listener : listeners) {
|
||||
// listener.onMessageReceived(message);
|
||||
// }
|
||||
|
||||
if ((message.getMsgType() == 1001 || message.getMsgType() == 1080) && publicScreenListeners.isEmpty()) {
|
||||
cacheMessage(message.getRoomId(), message);
|
||||
}
|
||||
|
||||
// 通知原有的监听器
|
||||
for (OnMessageReceivedListener listener : listeners) {
|
||||
listener.onMessageReceived(message);
|
||||
}
|
||||
|
||||
// 通知 PublicScreenEaseChatFragment 监听器
|
||||
for (PublicScreenMessageListener listener : publicScreenListeners) {
|
||||
listener.onPublicScreenMessageReceived(message);
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnMessageReceivedListener {
|
||||
void onMessageReceived(RoomMessageEvent message);
|
||||
}
|
||||
|
||||
|
||||
public void setOnMsgTaskListener(OnMsgTaskListener listener) {
|
||||
this.onMsgTaskListener = listener;
|
||||
}
|
||||
|
||||
public interface OnMsgTaskListener {
|
||||
void onMsgTask(RoomMessageEvent message);
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,8 @@ import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author qx
|
||||
* @data 2025/6/17
|
||||
@@ -52,7 +54,8 @@ public class MessageListenerSingleton {
|
||||
private List<OnMessageReceivedListener> listeners = new ArrayList<>();
|
||||
private V2TIMSimpleMsgListener simpleMsgListener;
|
||||
private V2TIMAdvancedMsgListener v2TIMAdvancedMsgListener;
|
||||
private static String mRoomId = "";
|
||||
@Getter
|
||||
public String mRoomId = "";
|
||||
public static String groupId;
|
||||
private V2TIMGroupListener groupListener;
|
||||
private V2TIMConversationListener conversationListener; // 需要保存引用
|
||||
@@ -96,7 +99,6 @@ public class MessageListenerSingleton {
|
||||
|
||||
// 同时修改 removePublicScreenMessageListener 方法
|
||||
public void removePublicScreenMessageListener(PublicScreenMessageListener listener) {
|
||||
mRoomId = "";
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
@@ -205,16 +207,16 @@ public class MessageListenerSingleton {
|
||||
|
||||
// 修改 joinGroup 方法,确保先退出再加入
|
||||
public void joinGroup(String roomId) {
|
||||
|
||||
if (TextUtils.isEmpty(roomId)) {
|
||||
return;
|
||||
}
|
||||
if (Objects.equals(mRoomId, roomId))
|
||||
return;
|
||||
|
||||
synchronized (groupOperationLock) {
|
||||
if (isGroupOperationInProgress) {
|
||||
// 如果有操作正在进行,延迟执行
|
||||
mainHandler.removeCallbacksAndMessages(null);
|
||||
mainHandler.postDelayed(() -> joinGroup(roomId), 100);
|
||||
mainHandler.postDelayed(() -> joinGroup(roomId), 200);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -313,7 +315,7 @@ public class MessageListenerSingleton {
|
||||
simpleMsgListener = new V2TIMSimpleMsgListener() {
|
||||
@Override
|
||||
public void onRecvC2CTextMessage(String msgID, V2TIMUserInfo sender, String text) {
|
||||
LogUtils.d("C2C 文本消息 " + sender.getNickName());
|
||||
LogUtils.d("C2C 文本消息 " + text);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -321,7 +323,9 @@ public class MessageListenerSingleton {
|
||||
LogUtils.d("C2C 自定义(信令)消息 " + sender.getNickName());
|
||||
String message = new String(customData, StandardCharsets.UTF_8);
|
||||
RoomMessageEvent event = GsonUtils.fromJson(message, RoomMessageEvent.class);
|
||||
if (event.getMsgType() == 130 || event.getMsgType() == 131) {
|
||||
if (event.getMsgType() == 404){
|
||||
CommonAppContext.getInstance().clearLoginDialog(event.getText().getText());
|
||||
}else if (event.getMsgType() == 130 || event.getMsgType() == 131) {
|
||||
// EventBus.getDefault().post(event);
|
||||
RetrofitClient.getInstance().getCpListener().onReceiveMsg(event);
|
||||
} else if (event.getMsgType() == CustomMsgCode.INSTANCE.getCODE_TASK_APPRENTICE_JOIN_ROOM()) {
|
||||
@@ -340,12 +344,14 @@ public class MessageListenerSingleton {
|
||||
|
||||
@Override
|
||||
public void onRecvGroupCustomMessage(String msgID, String groupID, V2TIMGroupMemberInfo sender, byte[] customData) {
|
||||
LogUtils.d("收到群自定义消息:群组 " + groupID + " 中 " + sender.getNickName());
|
||||
LogUtils.d("收到群自定义消息:群组 " + groupID + " 中 " + sender.getNickName() +",mRoomId:"+mRoomId);
|
||||
if (!groupID.equals("")) {
|
||||
String message = new String(customData, StandardCharsets.UTF_8);
|
||||
RoomMessageEvent event = GsonUtils.fromJson(message, RoomMessageEvent.class);
|
||||
notifyMessageReceived(event);
|
||||
LogUtils.d("收到群自定义消息(信令):", message);
|
||||
if (groupID.replace("room","").equals(mRoomId)) {
|
||||
String message = new String(customData, StandardCharsets.UTF_8);
|
||||
RoomMessageEvent event = GsonUtils.fromJson(message, RoomMessageEvent.class);
|
||||
notifyMessageReceived(event);
|
||||
LogUtils.d("收到群自定义消息(信令):", message);
|
||||
}
|
||||
} else {
|
||||
String message = new String(customData, StandardCharsets.UTF_8);
|
||||
LogUtils.d("收到群自定义消息(信令):", message);
|
||||
|
||||
@@ -58,21 +58,11 @@ public abstract class BasePresenter<V extends IView> implements IPresenter {
|
||||
@Override
|
||||
public void detachView() {
|
||||
cancelRequest();
|
||||
if (MvpRef != null) {
|
||||
MvpRef.clear();
|
||||
MvpRef = null;
|
||||
}
|
||||
if (api != null) {
|
||||
api = null;
|
||||
}
|
||||
unBindView();
|
||||
}
|
||||
|
||||
|
||||
public void unBindView() {
|
||||
if (MvpRef != null) {
|
||||
MvpRef.clear();
|
||||
}
|
||||
mContext=null;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ public class RewardGiftContacts {
|
||||
void getGiftPack(String s);
|
||||
|
||||
void getGiftPackListCount(GiftPackListCount giftPackListCount);
|
||||
|
||||
void roomHotCard();
|
||||
}
|
||||
|
||||
public interface IIndexPre extends IPresenter {
|
||||
@@ -43,7 +45,7 @@ public class RewardGiftContacts {
|
||||
|
||||
void giveGift(String user_id, String gid, String num, String to_uid, String gift_type);
|
||||
|
||||
void roomGift(String room_id, String gift_id, String gift_num, String to_uid, String type, String pit_number,String heart_id);
|
||||
void roomGift(String room_id, String gift_id, String gift_num, String to_uid, String type, String pit_number,String heart_id,String gift_bag_id);
|
||||
|
||||
void wallet();
|
||||
|
||||
@@ -51,11 +53,13 @@ public class RewardGiftContacts {
|
||||
|
||||
void setRoomApply(String room_id, String gift_id,String gift_price);
|
||||
|
||||
void roomAuctionJoin(String auction_id,String user_id, String gift_id, String num,String type);
|
||||
void roomAuctionJoin(String auction_id,String user_id, String gift_id, String num,String type,String gift_bag_id);
|
||||
void giftPack();
|
||||
|
||||
void getGiftPack(String roomId,String userId,String heart_id,String auction_id );
|
||||
|
||||
void getGiftPackListCount();
|
||||
|
||||
void roomHotCard(String udid,String room_id,String num);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +46,8 @@ public class RewardGiftPresenter extends BasePresenter<RewardGiftContacts.View>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getGiftLabel(String have_hot) {
|
||||
RetrofitClient.getInstance().getGiftLabel(have_hot, new BaseObserver<List<GiftLabelBean>>() {
|
||||
public void getGiftLabel(String type) {
|
||||
RetrofitClient.getInstance().getGiftLabel(type, new BaseObserver<List<GiftLabelBean>>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
addDisposable(d);
|
||||
@@ -103,8 +103,8 @@ public class RewardGiftPresenter extends BasePresenter<RewardGiftContacts.View>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void roomGift(String room_id, String gift_id, String gift_num, String to_uid, String type, String pit_number, String heart_id) {
|
||||
RetrofitClient.getInstance().roomGift(room_id, gift_id, gift_num, to_uid, type, pit_number, heart_id, new BaseObserver<RoomGiftData>() {
|
||||
public void roomGift(String room_id, String gift_id, String gift_num, String to_uid, String type, String pit_number, String heart_id,String gift_bag_id) {
|
||||
RetrofitClient.getInstance().roomGift(room_id, gift_id, gift_num, to_uid, type, pit_number, heart_id,gift_bag_id, new BaseObserver<RoomGiftData>() {
|
||||
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
@@ -177,8 +177,8 @@ public class RewardGiftPresenter extends BasePresenter<RewardGiftContacts.View>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void roomAuctionJoin(String auction_id, String user_id, String gift_id, String num, String type) {
|
||||
RetrofitClient.getInstance().roomAuctionJoin(auction_id, user_id, gift_id, num, type, new BaseObserver<RoomAuction.AuctionListBean>() {
|
||||
public void roomAuctionJoin(String auction_id, String user_id, String gift_id, String num, String type,String gift_bg) {
|
||||
RetrofitClient.getInstance().roomAuctionJoin(auction_id, user_id, gift_id, num, type,gift_bg, new BaseObserver<RoomAuction.AuctionListBean>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
addDisposable(d);
|
||||
@@ -208,9 +208,6 @@ public class RewardGiftPresenter extends BasePresenter<RewardGiftContacts.View>
|
||||
if (MvpRef == null) {
|
||||
MvpRef = new WeakReference<>(mView);
|
||||
}
|
||||
if (giftPackBeans == null) {
|
||||
return;
|
||||
}
|
||||
MvpRef.get().giftPack(giftPackBeans);
|
||||
}
|
||||
});
|
||||
@@ -255,4 +252,23 @@ public class RewardGiftPresenter extends BasePresenter<RewardGiftContacts.View>
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void roomHotCard(String udid, String room_id, String num) {
|
||||
RetrofitClient.getInstance().roomHotCard(udid, room_id, num, new BaseObserver<String>() {
|
||||
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
addDisposable(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(String s) {
|
||||
if (MvpRef == null) {
|
||||
MvpRef = new WeakReference<>(mView);
|
||||
}
|
||||
MvpRef.get().roomHotCard();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ import android.content.Context;
|
||||
import android.media.projection.MediaProjection;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemClock;
|
||||
import android.text.TextUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
@@ -54,7 +56,9 @@ import java.io.FileInputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
@@ -90,7 +94,7 @@ import io.reactivex.disposables.Disposable;
|
||||
public class AgoraManager {
|
||||
|
||||
private static volatile AgoraManager instance;
|
||||
public RtcEngineEx rtcEngine;
|
||||
public RtcEngineEx rtcEngine;
|
||||
// private RtcEngineEx rtcEngineEx;
|
||||
private Context context;
|
||||
private boolean isLocalAudioEnabled = true; // 默认开启麦克风
|
||||
@@ -103,7 +107,7 @@ public class AgoraManager {
|
||||
|
||||
private static List<Music> musicList;
|
||||
private static boolean isBjMusic = false;
|
||||
private static List<SoundLevelUpdateListener> soundLevelUpdateListeners = new CopyOnWriteArrayList<>();
|
||||
private List<SoundLevelUpdateListener> soundLevelUpdateListeners = new CopyOnWriteArrayList<>();
|
||||
private static ChannelMediaOptions options;
|
||||
private static RtcConnection connection;
|
||||
private String pkRoomId = "";
|
||||
@@ -120,6 +124,12 @@ public class AgoraManager {
|
||||
private Disposable disposableB;
|
||||
private Disposable disposableC;
|
||||
|
||||
// UI 刷新最小间隔(ms)
|
||||
private static final long SOUND_UI_INTERVAL = 50;
|
||||
|
||||
private final Handler uiHandler = new Handler(Looper.getMainLooper());
|
||||
private long lastDispatchTime = 0;
|
||||
|
||||
public void setLastRoomId(String value) {
|
||||
lastRoomId = value;
|
||||
}
|
||||
@@ -187,7 +197,7 @@ public class AgoraManager {
|
||||
config.mAppId = appId;
|
||||
config.mEventHandler = getDefaultEventHandler();
|
||||
config.mChannelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
|
||||
config.mAudioScenario = Constants.AUDIO_SCENARIO_CHORUS;
|
||||
config.mAudioScenario = Constants.AUDIO_SCENARIO_GAME_STREAMING;
|
||||
config.mAreaCode = 1;
|
||||
|
||||
rtcEngine = (RtcEngineEx) RtcEngine.create(config);
|
||||
@@ -200,7 +210,7 @@ public class AgoraManager {
|
||||
try {
|
||||
rtcEngine.setAudioProfile(Constants.AUDIO_PROFILE_MUSIC_HIGH_QUALITY_STEREO,
|
||||
Constants.AUDIO_SCENARIO_GAME_STREAMING);
|
||||
rtcEngine.enableAudioVolumeIndication(200, 3, true);
|
||||
rtcEngine.enableAudioVolumeIndication(500, 3, true);
|
||||
rtcEngine.setClientRole(Constants.CLIENT_ROLE_BROADCASTER);
|
||||
rtcEngine.muteLocalAudioStream(true); // 默认静音
|
||||
rtcEngine.muteAllRemoteAudioStreams(false); // 监听远端的音频
|
||||
@@ -220,6 +230,9 @@ public class AgoraManager {
|
||||
"}" +
|
||||
"}");
|
||||
rtcEngine.setParameters("{\"che.video.mobile_1080p\":true}");
|
||||
|
||||
setEnable();
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtils.w("AgoraManager", "Failed to set parameters", e);
|
||||
}
|
||||
@@ -232,6 +245,7 @@ public class AgoraManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int calculateScreenAngle(int orientation) {
|
||||
if (orientation >= 315 || orientation < 45) {
|
||||
return 0; // 竖屏(0度)
|
||||
@@ -243,6 +257,7 @@ public class AgoraManager {
|
||||
return 270; // 横屏左(270度)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加入语音聊天房间
|
||||
*/
|
||||
@@ -271,6 +286,7 @@ public class AgoraManager {
|
||||
// 在频道中发布屏幕采集的音频
|
||||
options.publishScreenCaptureAudio = true;
|
||||
ClientRole(isCamerJs);
|
||||
|
||||
// options.publishMediaPlayerId = 0;
|
||||
rtcEngine.joinChannel(token, mRoomId, uid, options);
|
||||
|
||||
@@ -279,6 +295,18 @@ public class AgoraManager {
|
||||
|
||||
}
|
||||
|
||||
public void setEnable(){
|
||||
if (SpUtil.getSkService()==1){
|
||||
rtcEngine.setParameters("{\"che.audio.aec.enable\":false}"); // 关闭回音消除
|
||||
rtcEngine.setParameters("{\"che.audio.ans.enable\":false}"); // 关闭降噪
|
||||
rtcEngine.setParameters("{\"che.audio.agc.enable\":false}"); // 关闭增益控制
|
||||
}else {
|
||||
rtcEngine.setParameters("{\"che.audio.aec.enable\":true}"); // 开启回音消除
|
||||
rtcEngine.setParameters("{\"che.audio.ans.enable\":true}"); // 开启降噪
|
||||
rtcEngine.setParameters("{\"che.audio.agc.enable\":true}"); // 开启增益控制
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理资源但保留实例
|
||||
*/
|
||||
@@ -332,14 +360,14 @@ public class AgoraManager {
|
||||
}
|
||||
handlers.clear();
|
||||
}
|
||||
if (disposableA != null && !disposableA.isDisposed()){
|
||||
if (disposableA != null && !disposableA.isDisposed()) {
|
||||
disposableA.dispose();
|
||||
}
|
||||
if (disposableB != null && !disposableB.isDisposed()){
|
||||
disposableB.dispose();
|
||||
if (disposableB != null && !disposableB.isDisposed()) {
|
||||
disposableB.dispose();
|
||||
}
|
||||
if (disposableC != null && !disposableC.isDisposed()){
|
||||
disposableC.dispose();
|
||||
if (disposableC != null && !disposableC.isDisposed()) {
|
||||
disposableC.dispose();
|
||||
}
|
||||
// 关闭线程池
|
||||
if (executorService != null && !executorService.isShutdown()) {
|
||||
@@ -396,14 +424,14 @@ public class AgoraManager {
|
||||
@Override
|
||||
public void onAudioEffectFinished(int soundId) {
|
||||
super.onAudioEffectFinished(soundId);
|
||||
LogUtils.e("onAudioEffectFinished", "soundId------>" + soundId);
|
||||
// LogUtils.e("onAudioEffectFinished", "soundId------>" + soundId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteAudioStateChanged(int uid, int state, int reason, int elapsed) {
|
||||
super.onRemoteAudioStateChanged(uid, state, reason, elapsed);
|
||||
if (state == 0){
|
||||
LogUtils.e("onRemoteAudioStateChanged", "uid------>" + uid, "state------>" + state, "reason------>" + reason, "elapsed------>" + elapsed);
|
||||
if (state == 0) {
|
||||
// LogUtils.e("onRemoteAudioStateChanged", "uid------>" + uid, "state------>" + state, "reason------>" + reason, "elapsed------>" + elapsed);
|
||||
for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) {
|
||||
if (listener != null) {
|
||||
// Pk 关闭远端推流
|
||||
@@ -416,7 +444,7 @@ public class AgoraManager {
|
||||
@Override
|
||||
public void onUserMuteAudio(int uid, boolean muted) {
|
||||
super.onUserMuteAudio(uid, muted);
|
||||
LogUtils.e("onUserMuteAudio", "uid------>" + uid, "muted------>" + muted);
|
||||
// LogUtils.e("onUserMuteAudio", "uid------>" + uid, "muted------>" + muted);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -475,7 +503,7 @@ public class AgoraManager {
|
||||
@Override
|
||||
public void onLyricResult(String requestId, long songCode, String lyricUrl, int reason) {
|
||||
if (lyricUrl != null) {
|
||||
LogUtils.e("roomInfoEvent",lyricUrl);
|
||||
LogUtils.e("roomInfoEvent", lyricUrl);
|
||||
getLyricsInstance(lyricUrl);
|
||||
}
|
||||
}
|
||||
@@ -549,17 +577,31 @@ public class AgoraManager {
|
||||
|
||||
if (speakers == null || speakers.length == 0) return;
|
||||
|
||||
for (final AudioVolumeInfo info : speakers) {
|
||||
final int uid = info.uid;
|
||||
final int volume = info.volume;
|
||||
// 1️⃣ 构建局部 Map(声网线程私有)
|
||||
Map<String, Integer> localMap = new HashMap<>();
|
||||
for (AudioVolumeInfo info : speakers) {
|
||||
String userId = (info.uid == 0)
|
||||
? SpUtil.getUserId() + ""
|
||||
: String.valueOf(info.uid);
|
||||
localMap.put(userId, info.volume);
|
||||
}
|
||||
|
||||
// long now = SystemClock.uptimeMillis();
|
||||
// if (now - lastDispatchTime < SOUND_UI_INTERVAL) return;
|
||||
// lastDispatchTime = now;
|
||||
|
||||
// 2️⃣ 只把“不可变快照”丢给 UI
|
||||
uiHandler.post(() -> dispatchVolume(localMap));
|
||||
}
|
||||
|
||||
private void dispatchVolume(Map<String, Integer> volumeSnapshot) {
|
||||
if (soundLevelUpdateListeners.isEmpty()) return;
|
||||
|
||||
for (Map.Entry<String, Integer> entry : volumeSnapshot.entrySet()) {
|
||||
|
||||
// 回调所有监听器
|
||||
for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) {
|
||||
if (listener != null) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
// 远程用户音量变化
|
||||
listener.onRemoteSoundLevelUpdate(uid > 0 ? String.valueOf(uid) : SpUtil.getUserId() + "", volume);
|
||||
});
|
||||
listener.onRemoteSoundLevelUpdate(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -636,6 +678,7 @@ public class AgoraManager {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并返回 IMediaPlayerObserver 实例
|
||||
*/
|
||||
@@ -686,37 +729,37 @@ public class AgoraManager {
|
||||
|
||||
@Override
|
||||
public void onPlayerEvent(io.agora.mediaplayer.Constants.MediaPlayerEvent eventCode, long elapsedTime, String message) {
|
||||
LogUtils.e("@@@", "eventCode: " + eventCode + ", elapsedTime: " + elapsedTime + ", message: " + message);
|
||||
// LogUtils.e("@@@", "eventCode: " + eventCode + ", elapsedTime: " + elapsedTime + ", message: " + message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMetaData(io.agora.mediaplayer.Constants.MediaPlayerMetadataType type, byte[] data) {
|
||||
LogUtils.e("@@@", "type: " + type + ", data: " + data);
|
||||
// LogUtils.e("@@@", "type: " + type + ", data: " + data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayBufferUpdated(long playCachedBuffer) {
|
||||
LogUtils.e("@@@", "playCachedBuffer: " + playCachedBuffer);
|
||||
// LogUtils.e("@@@", "playCachedBuffer: " + playCachedBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreloadEvent(String src, io.agora.mediaplayer.Constants.MediaPlayerPreloadEvent event) {
|
||||
LogUtils.e("@@@", "src: " + src + ", event: " + event);
|
||||
// LogUtils.e("@@@", "src: " + src + ", event: " + event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAgoraCDNTokenWillExpire() {
|
||||
LogUtils.e("@@@", "onAgoraCDNTokenWillExpire");
|
||||
// LogUtils.e("@@@", "onAgoraCDNTokenWillExpire");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerSrcInfoChanged(SrcInfo from, SrcInfo to) {
|
||||
LogUtils.e("@@@", "from: " + from + ", to: " + to);
|
||||
// LogUtils.e("@@@", "from: " + from + ", to: " + to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerInfoUpdated(PlayerUpdatedInfo info) {
|
||||
LogUtils.e("@@@", "info: " + info);
|
||||
// LogUtils.e("@@@", "info: " + info);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -733,6 +776,7 @@ public class AgoraManager {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void potexao(String page) {
|
||||
ClientRole(true);
|
||||
rtcEngine.playEffect(1, page, 0, 1, 0, 100, true);
|
||||
@@ -748,7 +792,7 @@ public class AgoraManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void joinChannelEx(String token, String channelId, int uid,String pkUserIds) {
|
||||
public void joinChannelEx(String token, String channelId, int uid, String pkUserIds) {
|
||||
if (rtcEngine == null) {
|
||||
init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId());
|
||||
}
|
||||
@@ -788,17 +832,17 @@ public class AgoraManager {
|
||||
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
Display display = manager.getDefaultDisplay();
|
||||
|
||||
DisplayMetrics outMetrics=new DisplayMetrics();
|
||||
DisplayMetrics outMetrics = new DisplayMetrics();
|
||||
display.getMetrics(outMetrics);
|
||||
|
||||
// // 设置屏幕采集的参数
|
||||
screenCaptureParameters.captureVideo = true;
|
||||
screenCaptureParameters.videoCaptureParameters.width = outMetrics.widthPixels;
|
||||
screenCaptureParameters.videoCaptureParameters.height = outMetrics.heightPixels;
|
||||
screenCaptureParameters.videoCaptureParameters.width = outMetrics.widthPixels;
|
||||
screenCaptureParameters.videoCaptureParameters.height = outMetrics.heightPixels;
|
||||
screenCaptureParameters.videoCaptureParameters.framerate = 15;
|
||||
screenCaptureParameters.captureAudio = true;
|
||||
screenCaptureParameters.audioCaptureParameters.captureSignalVolume =50;
|
||||
screenCaptureParameters.videoCaptureParameters.contentHint=1 ;
|
||||
screenCaptureParameters.audioCaptureParameters.captureSignalVolume = 50;
|
||||
screenCaptureParameters.videoCaptureParameters.contentHint = 1;
|
||||
rtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
|
||||
VD_1280x720,
|
||||
FRAME_RATE_FPS_15,
|
||||
@@ -811,12 +855,12 @@ public class AgoraManager {
|
||||
}
|
||||
|
||||
|
||||
public void setExternalMediaProjection(MediaProjection[] mediaProjection){
|
||||
public void setExternalMediaProjection(MediaProjection[] mediaProjection) {
|
||||
rtcEngine.setExternalMediaProjection(mediaProjection[0]);
|
||||
}
|
||||
|
||||
public void isPost(){
|
||||
if (rtcEngine != null){
|
||||
public void isPost() {
|
||||
if (rtcEngine != null) {
|
||||
ScreenCaptureParameters screenCaptureParameters = new ScreenCaptureParameters();
|
||||
|
||||
// 设置新的屏幕共享参数
|
||||
@@ -895,6 +939,7 @@ public class AgoraManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//关闭对方的所有推流
|
||||
public void muteAllRemoteAudioStreamsEx(boolean enabled) {
|
||||
if (rtcEngine == null) {
|
||||
@@ -910,10 +955,11 @@ public class AgoraManager {
|
||||
// rtcEngine.muteAllRemoteAudioStreamsEx(enabled, connection);
|
||||
}
|
||||
}
|
||||
|
||||
//打开对方支持的推流
|
||||
public void muteAllRemoteAudioStreamsExUserId(boolean enabled){
|
||||
if (rtcEngine != null){
|
||||
rtcEngine.muteRemoteAudioStreamEx(pkUserId,enabled,connection);
|
||||
public void muteAllRemoteAudioStreamsExUserId(boolean enabled) {
|
||||
if (rtcEngine != null) {
|
||||
rtcEngine.muteRemoteAudioStreamEx(pkUserId, enabled, connection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -989,6 +1035,7 @@ public class AgoraManager {
|
||||
// }
|
||||
// }
|
||||
public void addSoundLevelListener(SoundLevelUpdateListener listener) {
|
||||
LogUtils.e("AgoraManager", "addSoundLevelListener: " + listener + "============" + soundLevelUpdateListeners.size());
|
||||
if (soundLevelUpdateListeners != null) {
|
||||
soundLevelUpdateListeners.add(listener);
|
||||
}
|
||||
@@ -1000,10 +1047,24 @@ public class AgoraManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void removeSoundLevelListenerAll() {
|
||||
if (soundLevelUpdateListeners != null)
|
||||
soundLevelUpdateListeners.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method searches for music based on a given keyword and page number.
|
||||
* It initializes the music content center if it's not already created.
|
||||
*
|
||||
* @param keyword The keyword to search for music
|
||||
* @param page The page number of the search results
|
||||
*/
|
||||
public void searchMusic(String keyword, int page) {
|
||||
// Check if musicContentCenter is initialized, if not create it
|
||||
if (musicContentCenter == null) {
|
||||
musicContentCenter = IAgoraMusicContentCenter.create(rtcEngine);
|
||||
}
|
||||
// Perform the music search with the keyword, page number and page size (20)
|
||||
musicContentCenter.searchMusic(keyword, page, 20);
|
||||
}
|
||||
|
||||
@@ -1075,8 +1136,8 @@ public class AgoraManager {
|
||||
String result = musicContentCenter.preload(mSongCode);
|
||||
// 使用后台线程池处理预加载检查,避免阻塞UI线程
|
||||
disposableC = Observable.timer(3000, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(aLong -> {
|
||||
isPreload(mSongCode, type);
|
||||
});
|
||||
isPreload(mSongCode, type);
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
musicPlayer.open(mSongCode, 0);
|
||||
@@ -1225,15 +1286,17 @@ public class AgoraManager {
|
||||
public void setPlayoutVolume(int volume) {
|
||||
if (musicPlayer != null) {
|
||||
musicPlayer.adjustPlayoutVolume(volume);//调节本地播放音量。 参数是0-100
|
||||
musicPlayer.adjustPublishSignalVolume(volume*2);//调节远端用户听到的音量。 参数是0-400
|
||||
musicPlayer.adjustPublishSignalVolume(volume * 2);//调节远端用户听到的音量。 参数是0-400
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 伴奏音量
|
||||
*
|
||||
* @param volume
|
||||
*/
|
||||
public void setAdjustPublishSignalVolume(int volume){
|
||||
public void setAdjustPublishSignalVolume(int volume) {
|
||||
musicPlayer.adjustPublishSignalVolume(volume);//调节远端用户听到的音量。 参数是0-400
|
||||
}
|
||||
|
||||
@@ -1325,7 +1388,7 @@ public class AgoraManager {
|
||||
.build();
|
||||
if (StatusUtil.isCompleted(task)) {
|
||||
MusicFileBean musicFileBean = new MusicFileBean();
|
||||
LogUtils.e("roomInfoEvent",convertFileToByteArray(task.getFile()));
|
||||
LogUtils.e("roomInfoEvent", convertFileToByteArray(task.getFile()));
|
||||
musicFileBean.setFileData(convertFileToByteArray(task.getFile()));
|
||||
EventBus.getDefault().post(musicFileBean);
|
||||
} else {
|
||||
@@ -1343,18 +1406,18 @@ public class AgoraManager {
|
||||
|
||||
@Override
|
||||
public void connected(@NonNull DownloadTask task, int blockCount, long currentOffset, long totalLength) {
|
||||
com.xscm.moduleutil.utils.logger.Logger.e("connected", blockCount);
|
||||
// com.xscm.moduleutil.utils.logger.Logger.e("connected", blockCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void progress(@NonNull DownloadTask task, long currentOffset, long totalLength) {
|
||||
com.xscm.moduleutil.utils.logger.Logger.e("progress", currentOffset);
|
||||
// com.xscm.moduleutil.utils.logger.Logger.e("progress", currentOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause, @NonNull Listener1Assist.Listener1Model model) {
|
||||
Logger.e("taskEnd", model);
|
||||
LogUtils.e("roomInfoEvent",convertFileToByteArray(task.getFile()));
|
||||
LogUtils.e("roomInfoEvent", convertFileToByteArray(task.getFile()));
|
||||
MusicFileBean musicFileBean = new MusicFileBean();
|
||||
musicFileBean.setFileData(convertFileToByteArray(task.getFile()));
|
||||
EventBus.getDefault().post(musicFileBean);
|
||||
|
||||
@@ -35,6 +35,7 @@ public class MqttConnect {
|
||||
public static String qx_hour_ranking = "";
|
||||
|
||||
public static String qx_redpacket_arrive = "";//红包飘屏的主题
|
||||
public static String qx_xianxuan = "";//炼仙传说推送
|
||||
Handler handler = new Handler(Looper.getMainLooper());
|
||||
String[] topic;
|
||||
int[] qos = {1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // 消息质量
|
||||
@@ -50,12 +51,14 @@ public class MqttConnect {
|
||||
update_app = "qx_xunlehui"; // 巡乐会飘屏
|
||||
qx_hour_ranking = "qx_hour_ranking";//小时榜飘屏
|
||||
qx_redpacket_arrive = "qx_redpacket_arrive"; //红包飘屏的主题
|
||||
qx_xianxuan = "qx_xianxuan"; //红包飘屏的主题
|
||||
|
||||
ArrayList<String> topicList = new ArrayList<>();
|
||||
topicList.add(shutdown);
|
||||
topicList.add(update_app);
|
||||
topicList.add(qx_hour_ranking);
|
||||
topicList.add(qx_redpacket_arrive);
|
||||
topicList.add(qx_xianxuan);
|
||||
topic = topicList.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@@ -93,6 +96,7 @@ public class MqttConnect {
|
||||
sub(update_app);
|
||||
sub(qx_hour_ranking);
|
||||
sub(qx_redpacket_arrive);
|
||||
sub(qx_xianxuan);
|
||||
|
||||
// UI操作回到主线程
|
||||
ActivityUtils.getTopActivity().runOnUiThread(() -> uiTip("MQTT连接成功"));
|
||||
@@ -139,8 +143,8 @@ public class MqttConnect {
|
||||
public void close() {
|
||||
if (mqttClient != null && mqttClient.isConnected()) {
|
||||
try {
|
||||
mqttClient.close();
|
||||
mqttClient.disconnect();
|
||||
mqttClient.close();
|
||||
mqttClient = null;
|
||||
} catch (MqttException e) {
|
||||
LogUtils.e(Tag, "关闭MQTT连接报错:" + e.getMessage());
|
||||
|
||||
@@ -6,9 +6,16 @@ import android.os.Looper;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.blankj.utilcode.util.GsonUtils;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.xscm.moduleutil.base.RealTimeMessages;
|
||||
import com.xscm.moduleutil.base.SocketBean;
|
||||
import com.xscm.moduleutil.bean.MqttXlhEnd;
|
||||
import com.xscm.moduleutil.bean.XLHBean;
|
||||
import com.xscm.moduleutil.bean.room.refining.MonsterEndBean;
|
||||
import com.xscm.moduleutil.bean.room.refining.MonsterInfoBean;
|
||||
import com.xscm.moduleutil.bean.room.refining.OpenMonsterBean;
|
||||
import com.xscm.moduleutil.event.HourlyBean;
|
||||
import com.xscm.moduleutil.event.RedBean;
|
||||
import com.xscm.moduleutil.event.RoomGiftRunable;
|
||||
@@ -59,6 +66,51 @@ public class MqttInitCallback implements MqttCallback {
|
||||
receiveQXHourRanking(topic, messageStr);
|
||||
} else if (topic.equals("qx_redpacket_arrive")) {
|
||||
receiveRed(topic, messageStr);
|
||||
} else if (topic.equals("qx_xianxuan")) {
|
||||
receiveXianxuanMessage(messageStr);
|
||||
}
|
||||
}
|
||||
|
||||
private void receiveXianxuanMessage(String messageStr) {
|
||||
try {
|
||||
JSONObject jsonObject = JSON.parseObject(messageStr);
|
||||
String message = jsonObject.getString("msg");
|
||||
// 将事件处理放到主线程执行
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
processXianxuanMessage(message);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
LogUtils.e("MQTT", "解析MQTT消息异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void processXianxuanMessage(String message) {
|
||||
SocketBean dataList = GsonUtils.fromJson(message, SocketBean.class);
|
||||
switch (dataList.getCode()) {
|
||||
case 3031:
|
||||
RealTimeMessages<MonsterInfoBean> monsterInfo = GsonUtils.fromJson(
|
||||
message,
|
||||
new TypeToken<RealTimeMessages<MonsterInfoBean>>() {}.getType()
|
||||
);
|
||||
EventBus.getDefault().post(monsterInfo.data);
|
||||
break;
|
||||
case 3032:
|
||||
// RealTimeMessages<OpenMonsterBean> openMonster =
|
||||
// GsonUtils.fromJson(
|
||||
// message,
|
||||
// new TypeToken<RealTimeMessages<OpenMonsterBean>>() {}.getType()
|
||||
// );
|
||||
// EventBus.getDefault().post(openMonster.data);
|
||||
break;
|
||||
case 3033:
|
||||
RealTimeMessages<MonsterEndBean> monsterEndBean =
|
||||
GsonUtils.fromJson(
|
||||
message,
|
||||
new TypeToken<RealTimeMessages<MonsterEndBean>>() {}.getType()
|
||||
);
|
||||
EventBus.getDefault().post(monsterEndBean.data);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.util.List;
|
||||
*/
|
||||
public class BackgroundManager {
|
||||
private static BackgroundManager instance;
|
||||
private String backgroundUrl;
|
||||
private int backgroundUrl;
|
||||
private Drawable backgroundDrawable;
|
||||
private List<BackgroundUpdateListener> listeners = new ArrayList<>();
|
||||
|
||||
@@ -31,12 +31,16 @@ public class BackgroundManager {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void setBackgroundUrl(String url) {
|
||||
public void setBackgroundUrl(int url) {
|
||||
this.backgroundUrl = url;
|
||||
loadBackground();
|
||||
// loadBackground();
|
||||
}
|
||||
// public void setBackgroundUrl(String url) {
|
||||
// this.backgroundUrl = url;
|
||||
// loadBackground();
|
||||
// }
|
||||
|
||||
public String getBackgroundUrl() {
|
||||
public int getBackgroundUrl() {
|
||||
return backgroundUrl;
|
||||
}
|
||||
|
||||
@@ -44,43 +48,42 @@ public class BackgroundManager {
|
||||
return backgroundDrawable;
|
||||
}
|
||||
|
||||
private void loadBackground() {
|
||||
if (backgroundUrl == null || backgroundUrl.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 这里使用一个临时的 ImageView 来加载图片
|
||||
// 实际项目中可能需要使用 Application Context
|
||||
// 为简化,这里直接加载到 drawable
|
||||
}
|
||||
// private void loadBackground() {
|
||||
// if (backgroundUrl == null || backgroundUrl.isEmpty()) {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
public void loadBackgroundDrawable(android.content.Context context, BackgroundLoadCallback callback) {
|
||||
if (backgroundUrl == null || backgroundUrl.isEmpty()) {
|
||||
if (backgroundUrl == 0 ) {
|
||||
callback.onLoadFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
Glide.with(context)
|
||||
.asDrawable()
|
||||
.load(backgroundUrl)
|
||||
.into(new CustomTarget<Drawable>() {
|
||||
@Override
|
||||
public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
|
||||
backgroundDrawable = resource;
|
||||
callback.onLoadSuccess(resource);
|
||||
notifyBackgroundUpdated(resource);
|
||||
}
|
||||
callback.onLoadComplete(backgroundUrl);
|
||||
|
||||
@Override
|
||||
public void onLoadCleared(Drawable placeholder) {
|
||||
callback.onLoadFailed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFailed(Drawable errorDrawable) {
|
||||
super.onLoadFailed(errorDrawable);
|
||||
callback.onLoadFailed();
|
||||
}
|
||||
});
|
||||
// Glide.with(context)
|
||||
// .asDrawable()
|
||||
// .load(backgroundUrl)
|
||||
// .into(new CustomTarget<Drawable>() {
|
||||
// @Override
|
||||
// public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
|
||||
// backgroundDrawable = resource;
|
||||
// callback.onLoadSuccess(resource);
|
||||
// notifyBackgroundUpdated(resource);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onLoadCleared(Drawable placeholder) {
|
||||
// callback.onLoadFailed();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onLoadFailed(Drawable errorDrawable) {
|
||||
// super.onLoadFailed(errorDrawable);
|
||||
// callback.onLoadFailed();
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
public void addListener(BackgroundUpdateListener listener) {
|
||||
@@ -102,6 +105,8 @@ public class BackgroundManager {
|
||||
public interface BackgroundLoadCallback {
|
||||
void onLoadSuccess(Drawable drawable);
|
||||
void onLoadFailed();
|
||||
|
||||
void onLoadComplete(int resultId);
|
||||
}
|
||||
|
||||
public interface BackgroundUpdateListener {
|
||||
|
||||
@@ -5,6 +5,9 @@ import android.graphics.Color;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.blankj.utilcode.util.ActivityUtils;
|
||||
import com.xscm.moduleutil.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -69,7 +72,7 @@ public class ColorManager {
|
||||
// 解析颜色为int值
|
||||
public int getPrimaryColorInt() {
|
||||
try {
|
||||
return Color.parseColor(primaryColor);
|
||||
return UtilConfig.getAttrColor(ActivityUtils.getTopActivity(), R.attr.app_color_colorPrimary);//Color.parseColor(primaryColor);
|
||||
} catch (Exception e) {
|
||||
return Color.parseColor("#3ABC6D"); // 默认颜色
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.xscm.moduleutil.utils
|
||||
|
||||
import androidx.lifecycle.LifecycleCoroutineScope
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.DecimalFormat
|
||||
|
||||
object CountDownUtil {
|
||||
/**
|
||||
* 倒计时的实现
|
||||
*/
|
||||
fun countDown(lifecycleScope: LifecycleCoroutineScope,
|
||||
time: Int = 5,
|
||||
start: (scop: CoroutineScope) -> Unit,
|
||||
end: () -> Unit,
|
||||
next: (time: Int) -> Unit
|
||||
) {
|
||||
lifecycleScope.launch {
|
||||
// 在这个范围内启动的协程会在Lifecycle被销毁的时候自动取消
|
||||
flow {
|
||||
(time downTo 0).forEach {
|
||||
delay(1000)
|
||||
emit(it)
|
||||
}
|
||||
}.onStart {
|
||||
// 倒计时开始 ,在这里可以让Button 禁止点击状态
|
||||
start(this@launch)
|
||||
}.onCompletion {
|
||||
// 倒计时结束 ,在这里可以让Button 恢复点击状态
|
||||
end()
|
||||
}.catch {
|
||||
//错误
|
||||
// YYLogUtils.e(it.message ?: "Unkown Error")
|
||||
}.collect {
|
||||
// 在这里 更新值来显示到UI
|
||||
next(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun formatCountDownTime(milliseconds: Long): String {
|
||||
val sb = StringBuilder()
|
||||
val mss = milliseconds * 1000 / 1000
|
||||
val days = mss / (60 * 60 * 24)
|
||||
val hours = mss % (60 * 60 * 24) / (60 * 60)
|
||||
val minutes = mss % (60 * 60) / 60
|
||||
val seconds = mss % 60
|
||||
val format = DecimalFormat("00")
|
||||
if (days > 0 || hours > 0) {
|
||||
sb.append(format.format(hours)).append(":").append(format.format(minutes)).append(":")
|
||||
.append(format.format(seconds))
|
||||
} else {
|
||||
sb.append(format.format(minutes)).append(":").append(format.format(seconds))
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -5,4 +5,6 @@ object CustomMsgCode {
|
||||
val CODE_TASK_APPRENTICE_JOIN_ROOM = 132
|
||||
val CODE_TASK_APPRENTICE_JOIN_ROOM_MSG = "您的师傅邀请您进入房间,您是否同意?"
|
||||
val CODE_TASK_APPRENTICE_JOIN_ROOM_MSG_REFUSE = "您的徒弟拒绝了您的邀请。"
|
||||
|
||||
val CODE_USER_SIGN_IN = "签到"
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import android.os.Looper;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.alibaba.android.arouter.utils.TextUtils;
|
||||
import com.blankj.utilcode.util.FileUtils;
|
||||
@@ -230,14 +229,14 @@ public class DownloadUtil {
|
||||
}
|
||||
}
|
||||
if (TextUtils.isEmpty(mApkPath)) {
|
||||
Log.e(TAG, "downloadApk: 存储路径为空了");
|
||||
LogUtils.e(TAG, "downloadApk: 存储路径为空了");
|
||||
return;
|
||||
}
|
||||
//建立一个文件
|
||||
mFile = new File(mApkPath);
|
||||
if (FileUtils.createFileByDeleteOldFile(mFile)) {
|
||||
if (mApi == null) {
|
||||
Log.e(TAG, "downloadApk: 下载接口为空了");
|
||||
LogUtils.e(TAG, "downloadApk: 下载接口为空了");
|
||||
return;
|
||||
}
|
||||
mCall = mApi.downloadFile(url);
|
||||
@@ -284,7 +283,7 @@ public class DownloadUtil {
|
||||
while ((len = is.read(buff)) != -1) {
|
||||
os.write(buff, 0, len);
|
||||
currentLength += len;
|
||||
Log.e(TAG, "当前进度: " + currentLength);
|
||||
LogUtils.e(TAG, "当前进度: " + currentLength);
|
||||
long finalCurrentLength = currentLength;
|
||||
HANDLER.post(new Runnable() {
|
||||
@Override
|
||||
|
||||
@@ -9,17 +9,28 @@ import android.graphics.ColorMatrix;
|
||||
import android.graphics.ColorMatrixColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.DecodeFormat;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.load.engine.GlideException;
|
||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
|
||||
import com.bumptech.glide.load.model.GlideUrl;
|
||||
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.bumptech.glide.signature.ObjectKey;
|
||||
import com.xscm.moduleutil.R;
|
||||
import com.xscm.moduleutil.widget.GrayscaleTransformation;
|
||||
|
||||
@@ -33,25 +44,164 @@ import java.security.MessageDigest;
|
||||
*/
|
||||
|
||||
public class ImageLoader {
|
||||
|
||||
private static RequestOptions createUrlOnlyOptions(String url) {
|
||||
String urls = String.valueOf(new GlideUrl(url));
|
||||
return new RequestOptions().signature(new ObjectKey(urls)).diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.skipMemoryCache(false)
|
||||
.format(DecodeFormat.PREFER_RGB_565);
|
||||
// 禁止尺寸影响缓存
|
||||
// .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
|
||||
}
|
||||
|
||||
public static void loadHead(Context context, ImageView view, String url) {
|
||||
RequestOptions options = RequestOptions.circleCropTransform();
|
||||
Glide.with(context).load(url).apply(options).error(com.xscm.moduleutil.R.mipmap.default_avatar).placeholder(R.mipmap.default_avatar).diskCacheStrategy(DiskCacheStrategy.ALL).into(view);
|
||||
Glide.with(context).load(url).apply(options).apply(createUrlOnlyOptions(url)).error(com.xscm.moduleutil.R.mipmap.default_avatar).placeholder(R.mipmap.default_avatar)
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:", e);
|
||||
return false;
|
||||
}
|
||||
}).thumbnail(0.3f).into(view);
|
||||
}
|
||||
|
||||
public static void loadHead(ImageView view, String url) {
|
||||
RequestOptions options = RequestOptions.circleCropTransform();
|
||||
Glide.with(view).load(url).apply(options).error(R.mipmap.default_avatar).placeholder(R.mipmap.default_avatar).diskCacheStrategy(DiskCacheStrategy.ALL).into(view);
|
||||
Glide.with(view).load(url).apply(options).apply(createUrlOnlyOptions(url)).error(R.mipmap.default_avatar).placeholder(R.mipmap.default_avatar)
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:", e);
|
||||
return false;
|
||||
}
|
||||
}).thumbnail(0.3f).into(view);
|
||||
}
|
||||
|
||||
public static void loadImage(ImageView view, String url) {
|
||||
Glide.with(view).load(url).error(R.mipmap.default_image).placeholder(R.mipmap.default_image).diskCacheStrategy(DiskCacheStrategy.ALL).into(view);
|
||||
RequestOptions options = RequestOptions.circleCropTransform();
|
||||
Glide.with(view).load(url).apply(options).apply(createUrlOnlyOptions(url)).error(R.mipmap.default_image).placeholder(R.mipmap.default_image)
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:", e);
|
||||
return false;
|
||||
}
|
||||
}).thumbnail(0.3f).into(view);
|
||||
}
|
||||
|
||||
public static void loadImage(Context context, ImageView view, String url) {
|
||||
Glide.with(context).load(url).error(R.mipmap.default_image).placeholder(R.mipmap.default_image)
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL).into(view);
|
||||
Glide.with(context).load(url).apply(createUrlOnlyOptions(url)).error(R.mipmap.default_image).placeholder(R.mipmap.default_image)
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:", e);
|
||||
return false;
|
||||
}
|
||||
}).thumbnail(0.3f).into(view);
|
||||
}
|
||||
/**
|
||||
* 加载图片并灰度
|
||||
@@ -62,13 +212,79 @@ public class ImageLoader {
|
||||
*/
|
||||
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);
|
||||
.error(R.mipmap.default_image).placeholder(R.mipmap.default_image).diskCacheStrategy(DiskCacheStrategy.RESOURCE)
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:", e);
|
||||
return false;
|
||||
}
|
||||
}).thumbnail(0.3f).into(view);
|
||||
}
|
||||
// 可调节灰度程度的方法
|
||||
public static void loadGrayscaleImage(Context context, String url, ImageView imageView, float saturation) {
|
||||
Glide.with(context)
|
||||
.load(url)
|
||||
.apply(RequestOptions.bitmapTransform(new GrayscaleTransformation(saturation)))
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:", e);
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
@@ -78,7 +294,7 @@ public class ImageLoader {
|
||||
} else {
|
||||
view.setVisibility(View.VISIBLE);
|
||||
}
|
||||
Glide.with(context).load(url).diskCacheStrategy(DiskCacheStrategy.ALL).into(view);
|
||||
Glide.with(context).load(url).diskCacheStrategy(DiskCacheStrategy.RESOURCE).into(view);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
@@ -26,13 +27,21 @@ import android.widget.LinearLayout;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.vectordrawable.graphics.drawable.Animatable2Compat;
|
||||
|
||||
import com.blankj.utilcode.util.ConvertUtils;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
import com.blankj.utilcode.util.Utils;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.integration.webp.decoder.WebpDrawable;
|
||||
import com.bumptech.glide.integration.webp.decoder.WebpDrawableTransformation;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.DecodeFormat;
|
||||
import com.bumptech.glide.load.Transformation;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.load.engine.GlideException;
|
||||
import com.bumptech.glide.load.model.GlideUrl;
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterInside;
|
||||
import com.bumptech.glide.load.resource.gif.GifDrawable;
|
||||
import com.bumptech.glide.request.FutureTarget;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
@@ -70,11 +79,54 @@ public class ImageUtils {
|
||||
|
||||
public static final int ANIM = -1;
|
||||
|
||||
private static RequestOptions createUrlOnlyOptions(String url) {
|
||||
return new RequestOptions().signature(new ObjectKey(url!=null ? url :"")).diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.skipMemoryCache(false)
|
||||
.format(DecodeFormat.PREFER_RGB_565)
|
||||
.error(new ColorDrawable(Color.TRANSPARENT)); // 透明错误图;
|
||||
|
||||
// 禁止尺寸影响缓存
|
||||
// .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认加载
|
||||
*/
|
||||
public static void loadImageView(String path, ImageView mImageView) {
|
||||
Glide.with(mImageView).load(path).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView);
|
||||
Glide.with(mImageView).load(path).apply(createUrlOnlyOptions(path))
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:", e);
|
||||
return false;
|
||||
}
|
||||
}).thumbnail(0.3f).into(mImageView);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,7 +134,40 @@ public class ImageUtils {
|
||||
*/
|
||||
public static void loadIcon(String path, ImageView mImageView) {
|
||||
mImageView.setVisibility(TextUtils.isEmpty(path) ? GONE : View.VISIBLE);
|
||||
Glide.with(mImageView).load(path).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView);
|
||||
Glide.with(mImageView).load(path).apply(createUrlOnlyOptions(path))
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:", e);
|
||||
return false;
|
||||
}
|
||||
}).thumbnail(0.3f).into(mImageView);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,8 +186,41 @@ public class ImageUtils {
|
||||
* @param height
|
||||
*/
|
||||
public static void loadSample(String path, ImageView mImageView, int width, int height) {
|
||||
RequestOptions options = new RequestOptions().override(width, height).diskCacheStrategy(DiskCacheStrategy.ALL);
|
||||
Glide.with(mImageView).load(path).apply(options).into(mImageView);
|
||||
RequestOptions options = new RequestOptions().override(width, height).diskCacheStrategy(DiskCacheStrategy.RESOURCE);
|
||||
Glide.with(mImageView).load(path).apply(options)
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:", e);
|
||||
return false;
|
||||
}
|
||||
}).thumbnail(0.3f).into(mImageView);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,7 +254,9 @@ public class ImageUtils {
|
||||
Glide.with(mImageView).load(path).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<Integer, SVGAVideoEntity> svgaCache = new HashMap<>();
|
||||
|
||||
// TODO: 2025/8/22 播放svga
|
||||
public static void loadDecorationAvatar2(int resourceId, SVGAImageView mImageView) {
|
||||
// 从资源文件夹加载SVGA文件
|
||||
@@ -155,7 +275,7 @@ public class ImageUtils {
|
||||
// 没有缓存,正常加载
|
||||
SVGAParser parser = SVGAParser.Companion.shareParser();
|
||||
InputStream inputStream = mImageView.getContext().getResources().openRawResource(resourceId);
|
||||
parser.decodeFromAssets("heart_line_31.svga", new SVGAParser.ParseCompletion() {
|
||||
parser.decodeFromAssets("heart_line_31.svga", new SVGAParser.ParseCompletion() {
|
||||
@Override
|
||||
public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) {
|
||||
if (mImageView != null) {
|
||||
@@ -179,7 +299,8 @@ public class ImageUtils {
|
||||
Logger.e("Resource ID is 0 or invalid");
|
||||
}
|
||||
}
|
||||
public static void loadSetErrorImg(String path, ImageView mImageView,int errorRes) {
|
||||
|
||||
public static void loadSetErrorImg(String path, ImageView mImageView, int errorRes) {
|
||||
if (mImageView == null) {
|
||||
return;
|
||||
}
|
||||
@@ -191,7 +312,40 @@ public class ImageUtils {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Glide.with(mImageView).load(path).error(errorRes).placeholder(errorRes).centerCrop().diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView);
|
||||
Glide.with(mImageView).load(path).apply(createUrlOnlyOptions(path)).error(errorRes).
|
||||
placeholder(errorRes).centerCrop().listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:", e);
|
||||
return false;
|
||||
}
|
||||
}).thumbnail(0.3f).into(mImageView);
|
||||
|
||||
}
|
||||
|
||||
@@ -207,7 +361,41 @@ public class ImageUtils {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Glide.with(mImageView).load(path).placeholder(R.mipmap.default_avatar).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView);
|
||||
Glide.with(mImageView).load(path).apply(createUrlOnlyOptions(path))
|
||||
.placeholder(R.mipmap.default_avatar).diskCacheStrategy(DiskCacheStrategy.RESOURCE)
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:"+path, e);
|
||||
return false;
|
||||
}
|
||||
}).thumbnail(0.3f).into(mImageView);
|
||||
}
|
||||
|
||||
public static void loadHeadCC(String path, ImageView mImageView) {
|
||||
@@ -221,7 +409,42 @@ 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).asBitmap().load(path)
|
||||
.apply(createUrlOnlyOptions(path)).listener(new RequestListener<Bitmap>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Bitmap resource, Object model,
|
||||
Target<Bitmap> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Bitmap> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:"+path, e);
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.error(R.mipmap.default_avatar).placeholder(R.mipmap.default_avatar).centerCrop()
|
||||
.thumbnail(0.3f).into(mImageView);
|
||||
}
|
||||
|
||||
public static void loadHead(String path, ImageView mImageView) {
|
||||
@@ -235,7 +458,40 @@ public class ImageUtils {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Glide.with(mImageView).load(path).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView);
|
||||
Glide.with(mImageView).load(path).apply(createUrlOnlyOptions(path))
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:"+path, e);
|
||||
return false;
|
||||
}
|
||||
}) .thumbnail(0.3f).into(mImageView);
|
||||
}
|
||||
|
||||
public static void loadHeadCC(String path, ImageView mImageView, LinearLayout.LayoutParams params) {
|
||||
@@ -249,8 +505,9 @@ public class ImageUtils {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Glide.with(mImageView).asBitmap().load(path).error(R.mipmap.default_avatar).placeholder(R.mipmap.default_avatar)
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
Glide.with(mImageView).asBitmap().load(path)
|
||||
.apply(createUrlOnlyOptions(path))
|
||||
.error(R.mipmap.default_avatar).placeholder(R.mipmap.default_avatar)
|
||||
// 添加加载监听
|
||||
.listener(new RequestListener<Bitmap>() {
|
||||
@Override
|
||||
@@ -262,10 +519,29 @@ public class ImageUtils {
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
|
||||
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
// 加载成功!resource 就是最终的 Bitmap 对象
|
||||
int imageWidth = resource.getWidth(); // 图片原始宽度
|
||||
int imageHeight = resource.getHeight(); // 图片原始高度
|
||||
params.width = (int)(imageWidth * 1.3);
|
||||
// params.width = (int) (imageWidth * 1.3);
|
||||
// 这里可以使用宽高(如打印、适配布局等)
|
||||
Log.d("GlideImageSize", "宽度:" + imageWidth + ",高度:" + imageHeight);
|
||||
return false; // 返回 false,Glide 会继续执行默认的图片设置(显示到 mImageView)
|
||||
@@ -283,22 +559,87 @@ public class ImageUtils {
|
||||
}
|
||||
|
||||
public static void loadCenterCrop(String path, ImageView mImageView) {
|
||||
Glide.with(mImageView).load(path).centerCrop().diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView);
|
||||
Glide.with(mImageView).load(path).apply(createUrlOnlyOptions(path)).centerCrop()
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:"+path, e);
|
||||
return false;
|
||||
}
|
||||
}).into(mImageView);
|
||||
}
|
||||
|
||||
public static void loadRes(int path, ImageView mImageView) {
|
||||
Glide.with(mImageView).load(path).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView);
|
||||
Glide.with(mImageView).load(path).diskCacheStrategy(DiskCacheStrategy.RESOURCE)
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
// dataSource 是关键参数!
|
||||
switch (dataSource) {
|
||||
case DATA_DISK_CACHE:
|
||||
case RESOURCE_DISK_CACHE:
|
||||
LogUtils.e("GlideCache", "来自磁盘缓存");
|
||||
break;
|
||||
case MEMORY_CACHE:
|
||||
LogUtils.e("GlideCache", "来自内存缓存");
|
||||
break;
|
||||
case LOCAL: // 本地文件
|
||||
LogUtils.e("GlideCache", "来自本地文件");
|
||||
break;
|
||||
case REMOTE: // 网络下载
|
||||
LogUtils.e("GlideCache", "来自网络下载");
|
||||
break;
|
||||
default:
|
||||
LogUtils.e("GlideCache", "来自: " + dataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model,
|
||||
Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e("GlideCache", "加载失败"+"path:"+path, e);
|
||||
return false;
|
||||
}
|
||||
}).into(mImageView);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载图片(优先使用本地缓存,无缓存则下载)
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param url 图片 URL
|
||||
* @param url 图片 URL
|
||||
* @param imageView 目标 ImageView
|
||||
*/
|
||||
public static void loadImageWithCache(Context context, String url, ImageView imageView) {
|
||||
public static void loadImageWithCache(String url, ImageView imageView) {
|
||||
if (TextUtils.isEmpty(url)) return;
|
||||
|
||||
// 去掉动态参数,提取稳定 URL
|
||||
@@ -306,9 +647,9 @@ public class ImageUtils {
|
||||
String signature = Md5Utils.getMD5String(stableUrl); // 使用 MD5 生成唯一签名
|
||||
|
||||
// Glide 加载配置
|
||||
Glide.with(context)
|
||||
Glide.with(imageView)
|
||||
.load(stableUrl)
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL) // 缓存所有版本
|
||||
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) // 缓存所有版本
|
||||
.signature(new ObjectKey(signature)) // 使用签名确保缓存一致
|
||||
.placeholder(R.mipmap.room_bj) // 加载中占位图
|
||||
.error(R.mipmap.room_bj) // 加载失败占位图
|
||||
@@ -427,7 +768,7 @@ public class ImageUtils {
|
||||
* @param listener 回调
|
||||
*/
|
||||
public static void loadBitmap(String path, final onLoadBitmap listener) {
|
||||
Glide.with(Utils.getApp()).asBitmap().load(path).into(new SimpleTarget<Bitmap>() {
|
||||
Glide.with(Utils.getApp()).asBitmap().load(path).apply(createUrlOnlyOptions(path)).into(new SimpleTarget<Bitmap>() {
|
||||
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
@@ -466,7 +807,8 @@ public class ImageUtils {
|
||||
}
|
||||
});
|
||||
}
|
||||
public static void loadIconByHeight1(String path, ImageView mImageView,int height) {
|
||||
|
||||
public static void loadIconByHeight1(String path, ImageView mImageView, int height) {
|
||||
mImageView.setVisibility(TextUtils.isEmpty(path) ? GONE : View.VISIBLE);
|
||||
Glide.with(mImageView).load(path).diskCacheStrategy(DiskCacheStrategy.ALL).into(new SimpleTarget<Drawable>() {
|
||||
@Override
|
||||
@@ -490,6 +832,7 @@ public class ImageUtils {
|
||||
Glide.with(imageView.getContext())
|
||||
.asBitmap()
|
||||
.load(url)
|
||||
.apply(createUrlOnlyOptions(url))
|
||||
.error(defaultResId) // 加载失败时显示默认图片
|
||||
.into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
@@ -519,8 +862,6 @@ public class ImageUtils {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 加载bitmap回调
|
||||
*/
|
||||
@@ -598,12 +939,13 @@ public class ImageUtils {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 assets 中的文件复制到指定路径
|
||||
*
|
||||
* @param assetName assets 中的文件名,例如:"my_file.txt"
|
||||
* @param savePath 要保存的目录路径,例如:"/data/data/your.package/files/"
|
||||
* @param saveName 保存后的文件名
|
||||
* @param assetName assets 中的文件名,例如:"my_file.txt"
|
||||
* @param savePath 要保存的目录路径,例如:"/data/data/your.package/files/"
|
||||
* @param saveName 保存后的文件名
|
||||
*/
|
||||
public static void copyAssetToFile(String assetName, String savePath, String saveName) {
|
||||
InputStream myInput = null;
|
||||
@@ -655,7 +997,55 @@ public class ImageUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearDiskCache(Context context){
|
||||
|
||||
public static void loadWebpOneStart(int webp_anim, ImageView mAnimView) {
|
||||
|
||||
if (mAnimView == null) {
|
||||
return;
|
||||
}
|
||||
// 1. 本地资源专属优化配置
|
||||
RequestOptions options = new RequestOptions()
|
||||
// 强制限制解码尺寸为ImageView显示尺寸(核心优化)
|
||||
.override(800, 800); // 本地图用原尺寸,或指定固定尺寸
|
||||
|
||||
//webp动图
|
||||
CenterInside transformation = new CenterInside();
|
||||
Glide.with(mAnimView)
|
||||
.load(webp_anim)//不是本地资源就改为url即可
|
||||
.apply(options)
|
||||
.optionalTransform(transformation)
|
||||
.optionalTransform(WebpDrawable.class, new WebpDrawableTransformation(transformation))
|
||||
.addListener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
|
||||
WebpDrawable webpDrawable = (WebpDrawable) resource;
|
||||
//需要设置为循环1次才会有onAnimationEnd回调
|
||||
webpDrawable.setLoopCount(1);
|
||||
webpDrawable.registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
|
||||
@Override
|
||||
public void onAnimationStart(Drawable drawable) {
|
||||
super.onAnimationStart(drawable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Drawable drawable) {
|
||||
super.onAnimationEnd(drawable);
|
||||
webpDrawable.unregisterAnimationCallback(this);
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.into(mAnimView);
|
||||
}
|
||||
|
||||
public static void clearDiskCache(Context context) {
|
||||
Glide.get(context).clearDiskCache();
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,10 @@ import com.xscm.moduleutil.R;
|
||||
import com.xscm.moduleutil.utils.logger.Logger;
|
||||
import com.xscm.moduleutil.widget.AvatarFrameView;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
|
||||
|
||||
/**
|
||||
* 描述 设置中的用户头像
|
||||
@@ -58,7 +62,10 @@ public class MeHeadView extends ConstraintLayout {
|
||||
mIvFrame.setVisibility(GONE);
|
||||
} else {
|
||||
mIvFrame.setVisibility(VISIBLE);
|
||||
mIvFrame.setSource(framePicture, 1);
|
||||
mIvFrame.stopPlay();
|
||||
Observable.timer(200, TimeUnit.MILLISECONDS).subscribe(aLong -> {
|
||||
mIvFrame.setSource(framePicture, 1);
|
||||
});
|
||||
}
|
||||
|
||||
if (nobilityImage != null && !TextUtils.isEmpty(nobilityImage)) {
|
||||
@@ -100,6 +107,7 @@ public class MeHeadView extends ConstraintLayout {
|
||||
|
||||
/**
|
||||
* 设置头像,性别,头像框,贵族
|
||||
*
|
||||
* @param sex
|
||||
* @param headPicture
|
||||
* @param framePicture
|
||||
|
||||
@@ -2,8 +2,12 @@ package com.xscm.moduleutil.utils;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
import com.xscm.moduleutil.bean.RedPacketInfo;
|
||||
import com.xscm.moduleutil.bean.room.EMMessageInfo;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@@ -50,15 +54,16 @@ public class QXRedPacketManager {
|
||||
*
|
||||
* @param redPackets 红包模型列表
|
||||
*/
|
||||
public void addRedPackets(List<RedPacketInfo> redPackets) {
|
||||
public void addRedPackets(String roomId,List<RedPacketInfo> redPackets) {
|
||||
if (redPackets == null || redPackets.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
this.redPackets.entrySet().removeIf(entry ->
|
||||
!(entry.getValue().getRoom_id()+"").equals(roomId));
|
||||
|
||||
for (RedPacketInfo model : redPackets) {
|
||||
this.redPackets.put(model.getRedpacket_id(), model);
|
||||
}
|
||||
|
||||
// 在添加数据后启动定时器(如果尚未启动)
|
||||
startCheckTimer();
|
||||
if (this.delegate != null && this.delegate instanceof QXRedPacketManagerDelegate) {
|
||||
@@ -71,17 +76,18 @@ public class QXRedPacketManager {
|
||||
*
|
||||
* @param redPacket 红包模型
|
||||
*/
|
||||
public void addRedPacket(RedPacketInfo redPacket) {
|
||||
public void addRedPacket(String roomId,RedPacketInfo redPacket) {
|
||||
if (redPacket == null || redPacket.getRedpacket_id() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.redPackets.entrySet().removeIf(entry ->
|
||||
!(entry.getValue().getRoom_id()+"").equals(roomId));
|
||||
this.redPackets.put(redPacket.getRedpacket_id(), redPacket);
|
||||
|
||||
// 在添加数据后启动定时器(如果尚未启动)
|
||||
startCheckTimer();
|
||||
if (this.delegate != null && this.delegate instanceof QXRedPacketManagerDelegate) {
|
||||
((QXRedPacketManagerDelegate) this.delegate).onRedPacketAdded(redPacket, this.redPackets.size());
|
||||
this.delegate.onRedPacketAdded(redPacket, this.redPackets.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,11 +96,19 @@ public class QXRedPacketManager {
|
||||
*
|
||||
* @param packetId 红包ID
|
||||
*/
|
||||
public void removeRedPacket(String packetId) {
|
||||
public void removeRedPacket(int status,String packetId) {
|
||||
if (status == EMMessageInfo.QXRoomMessageTypeQXRoomMessageRedRemove) {
|
||||
if (redPackets.get(packetId) != null) {
|
||||
RedPacketInfo info = redPackets.get(packetId);
|
||||
if (info.getCountdown() != 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.redPackets.remove(packetId);
|
||||
|
||||
if (this.delegate != null && this.delegate instanceof QXRedPacketManagerDelegate) {
|
||||
((QXRedPacketManagerDelegate) this.delegate).onRedPacketRemoved(packetId, this.redPackets.size());
|
||||
this.delegate.onRedPacketRemoved(packetId, this.redPackets.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +164,6 @@ public class QXRedPacketManager {
|
||||
|
||||
for (RedPacketInfo packet : packets) {
|
||||
long packetTime = packet.remainingTime();
|
||||
LogUtils.e("红包剩余时间:" + packet.getRedpacket_time());
|
||||
long redpacketTime = 0;
|
||||
try {
|
||||
if (packet.getRedpacket_time() != null) {
|
||||
@@ -159,11 +172,11 @@ public class QXRedPacketManager {
|
||||
} catch (NumberFormatException e) {
|
||||
LogUtils.e("红包时间格式错误: " + packet.getRedpacket_time());
|
||||
}
|
||||
if (packetTime <= -redpacketTime) {
|
||||
|
||||
removeRedPacket(packet.getRedpacket_id());
|
||||
}
|
||||
if (packet.getCountdown()==0){
|
||||
if (packetTime <= -redpacketTime) {
|
||||
removeRedPacket(0,packet.getRedpacket_id());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -180,6 +193,10 @@ public class QXRedPacketManager {
|
||||
((QXRedPacketManagerDelegate) this.delegate).onRedPacketUpdated(packet, this.redPackets.size());
|
||||
}
|
||||
}
|
||||
|
||||
if (packetTime <= 0) {
|
||||
removeRedPacket(0,packet.getRedpacket_id());
|
||||
}
|
||||
}
|
||||
|
||||
// 继续执行定时任务
|
||||
|
||||
@@ -18,6 +18,7 @@ public class SPConstants {
|
||||
public static final String VOLUME = "VOLUME"; //音量
|
||||
public static final String CURRENT_MUSIC = "CURRENT_MUSIC"; //当前播放音乐
|
||||
public static final String OPEN_EFFECT = "OPEN_EFFECT"; //开启特效
|
||||
public static final String RED_SOUND = "RED_SOUND"; //开启红包声音
|
||||
public static final String OPEN_AU_BACK = "OPEN_AU_BACK"; //开启耳返
|
||||
public static final String ORDER_NEWS_COUNT = "orderNewsCount";
|
||||
public static final String ORDER_LAST_MSG = "lastOrderMsg";
|
||||
@@ -31,7 +32,9 @@ public class SPConstants {
|
||||
|
||||
public static final String USER_INFO = "userInfo";
|
||||
|
||||
public static final String FLOATING_SCREEN = "floatingScreen";
|
||||
public static final String FLOATING_SCREEN = "floatingScreen";//飘屏开关
|
||||
|
||||
public static final String SHELF="shelf";
|
||||
public static final String SHELF = "shelf";//是否打开趣味玩法
|
||||
|
||||
public static final String TASK_SERVICE="taskService";//切换服务器
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.text.TextUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.blankj.utilcode.util.SPUtils;
|
||||
import com.xscm.moduleutil.base.CommonAppContext;
|
||||
import com.xscm.moduleutil.bean.AppCustomerBean;
|
||||
import com.xscm.moduleutil.bean.UserBean;
|
||||
import com.xscm.moduleutil.bean.UserInfo;
|
||||
|
||||
@@ -233,6 +234,16 @@ public class SpUtil {
|
||||
return SPUtils.getInstance(SPConstants.PREFERENCE_NAME).getString(SPConstants.TOKEN);
|
||||
}
|
||||
|
||||
public static void setAppCustomerBean(AppCustomerBean appCustomerBean) {
|
||||
String s = JSON.toJSONString(appCustomerBean);
|
||||
SPUtils.getInstance(SPConstants.PREFERENCE_NAME).put("appCustomerBean", s, true);
|
||||
}
|
||||
|
||||
public static AppCustomerBean getAppCustomerBean() {
|
||||
String s = SPUtils.getInstance(SPConstants.PREFERENCE_NAME).getString("appCustomerBean");
|
||||
return JSON.parseObject(s, AppCustomerBean.class);
|
||||
}
|
||||
|
||||
public static void setBoolean(String key, boolean value) {
|
||||
SPUtils.getInstance(SPConstants.PREFERENCE_NAME).put(key, value, true);
|
||||
}
|
||||
@@ -335,6 +346,23 @@ public class SpUtil {
|
||||
return shelf;
|
||||
}
|
||||
|
||||
public static int setTaskService(int taskService){
|
||||
SPUtils.getInstance(SPConstants.PREFERENCE_NAME).put(SPConstants.TASK_SERVICE, taskService);
|
||||
return taskService;
|
||||
}
|
||||
public static int getTaskService(){
|
||||
return SPUtils.getInstance(SPConstants.PREFERENCE_NAME).getInt(SPConstants.TASK_SERVICE);
|
||||
}
|
||||
|
||||
public static int setSkService(int taskService){
|
||||
SPUtils.getInstance(SPConstants.PREFERENCE_NAME).put("skService", taskService);
|
||||
return taskService;
|
||||
}
|
||||
public static int getSkService(){
|
||||
return SPUtils.getInstance(SPConstants.PREFERENCE_NAME).getInt("skService");
|
||||
}
|
||||
|
||||
|
||||
//获取SharedPreferences音乐轮播方式
|
||||
public static int getPlayPattern() {
|
||||
return SPUtils.getInstance(SPConstants.PREFERENCE_NAME).getInt(SPConstants.PLAY_MODE, 1);
|
||||
@@ -370,6 +398,14 @@ public class SpUtil {
|
||||
SPUtils.getInstance(SPConstants.PREFERENCE_NAME).put(SPConstants.OPEN_EFFECT, i);
|
||||
}
|
||||
|
||||
public static void setRedSound(int i){
|
||||
SPUtils.getInstance(SPConstants.PREFERENCE_NAME).put(SPConstants.RED_SOUND, i);
|
||||
}
|
||||
|
||||
public static int getRedSound(){
|
||||
return SPUtils.getInstance(SPConstants.PREFERENCE_NAME).getInt(SPConstants.RED_SOUND, 1);
|
||||
}
|
||||
|
||||
//获取开启特效
|
||||
public static int getOpenEffect() {
|
||||
return SPUtils.getInstance(SPConstants.PREFERENCE_NAME).getInt(SPConstants.OPEN_EFFECT, 1);
|
||||
|
||||
@@ -4,8 +4,8 @@ import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import com.blankj.utilcode.util.AppUtils;
|
||||
import com.blankj.utilcode.util.DeviceUtils;
|
||||
import com.blankj.utilcode.util.MetaDataUtils;
|
||||
import com.chad.library.BuildConfig;
|
||||
import com.xscm.moduleutil.base.CommonAppContext;
|
||||
import com.xscm.moduleutil.utils.config.ConfigUtils;
|
||||
|
||||
@@ -78,7 +78,8 @@ public class SystemUtils {
|
||||
}
|
||||
|
||||
public static String getShortClientID(Context context) {
|
||||
String cid = getClientID("xqipaoandroid");
|
||||
// String cid = getClientID("xqipaoandroid");
|
||||
String cid = DeviceUtils.getUniqueDeviceId();
|
||||
return Md5Utils.get(cid + getUUID(context));
|
||||
}
|
||||
|
||||
@@ -90,7 +91,7 @@ public class SystemUtils {
|
||||
ConfigUtils configUtils = ConfigUtils.getInstance(context);
|
||||
configUtils.setConfigName(system_uuid_key);
|
||||
String system_config_uuid = configUtils.findStringByKey(system_uuid_key);
|
||||
if (system_config_uuid == null) {
|
||||
if (system_config_uuid == null || system_config_uuid.isEmpty()) {
|
||||
// system_config_uuid = DeviceUtils.getUniqueDeviceId();
|
||||
configUtils.addOrUpdateText(system_uuid_key, system_config_uuid);
|
||||
}
|
||||
@@ -106,9 +107,9 @@ public class SystemUtils {
|
||||
public static Map<String, String> getSystemParams() {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("deviceId", SystemUtils.getShortClientID(CommonAppContext.getInstance()));
|
||||
headers.put("appVersion", BuildConfig.VERSION_NAME + "." + BuildConfig.VERSION_CODE);
|
||||
headers.put("versionName", BuildConfig.VERSION_NAME);
|
||||
headers.put("versionCode", String.valueOf(BuildConfig.VERSION_CODE));
|
||||
headers.put("appId", CommonAppContext.getInstance().appId);
|
||||
headers.put("versionName", CommonAppContext.getInstance().appVersionName);
|
||||
headers.put("versionCode", CommonAppContext.getInstance().appVersionCode);
|
||||
headers.put("system", "android");
|
||||
headers.put("emulator", CommonAppContext.getInstance().emulator);
|
||||
headers.put("deviceName", SystemUtils.getDeviceBrand() + SystemUtils.getSystemModel() + SystemUtils.getSystemVersion());
|
||||
|
||||
142
BaseModule/src/main/java/com/xscm/moduleutil/utils/TTSManager.kt
Normal file
142
BaseModule/src/main/java/com/xscm/moduleutil/utils/TTSManager.kt
Normal file
@@ -0,0 +1,142 @@
|
||||
package com.xscm.moduleutil.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.speech.tts.TextToSpeech
|
||||
import android.speech.tts.UtteranceProgressListener
|
||||
import java.util.LinkedList
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2025/12/6 11:00
|
||||
* 用途:
|
||||
*/
|
||||
class TTSManager private constructor(context: Context) :
|
||||
TextToSpeech.OnInitListener {
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var instance: TTSManager? = null
|
||||
|
||||
fun getInstance(context: Context): TTSManager {
|
||||
return instance ?: synchronized(this) {
|
||||
instance ?: TTSManager(context.applicationContext).also {
|
||||
instance = it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var tts: TextToSpeech? = null
|
||||
private var isInitialized = false
|
||||
private val pendingQueue = LinkedList<String>()
|
||||
private var currentLanguage = Locale.CHINESE
|
||||
|
||||
init {
|
||||
initTTS(context)
|
||||
}
|
||||
|
||||
private fun initTTS(context: Context) {
|
||||
tts = TextToSpeech(context, this).apply {
|
||||
setOnUtteranceProgressListener(object : UtteranceProgressListener() {
|
||||
override fun onStart(utteranceId: String?) {
|
||||
// 开始朗读
|
||||
}
|
||||
|
||||
override fun onDone(utteranceId: String?) {
|
||||
// 朗读完成
|
||||
}
|
||||
|
||||
override fun onError(utteranceId: String?) {
|
||||
// 发生错误
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun onInit(status: Int) {
|
||||
isInitialized = if (status == TextToSpeech.SUCCESS) {
|
||||
setLanguage(currentLanguage)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
if (isInitialized) {
|
||||
processPendingQueue()
|
||||
}
|
||||
}
|
||||
|
||||
fun speak(text: String, flush: Boolean = true) {
|
||||
if (!isInitialized || tts == null) {
|
||||
pendingQueue.add(text)
|
||||
return
|
||||
}
|
||||
|
||||
val utteranceId = System.currentTimeMillis().toString()
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
val params = Bundle().apply {
|
||||
putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utteranceId)
|
||||
}
|
||||
tts?.speak(text,
|
||||
if (flush) TextToSpeech.QUEUE_FLUSH else TextToSpeech.QUEUE_ADD,
|
||||
params,
|
||||
utteranceId)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
val params = HashMap<String, String>()
|
||||
params[TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID] = utteranceId
|
||||
tts?.speak(text,
|
||||
if (flush) TextToSpeech.QUEUE_FLUSH else TextToSpeech.QUEUE_ADD,
|
||||
params)
|
||||
}
|
||||
}
|
||||
|
||||
fun setLanguage(locale: Locale): Boolean {
|
||||
currentLanguage = locale
|
||||
return if (isInitialized) {
|
||||
tts?.setLanguage(locale) == TextToSpeech.LANG_COUNTRY_AVAILABLE
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
tts?.stop()
|
||||
}
|
||||
|
||||
fun pause() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
tts?.stop()
|
||||
}
|
||||
}
|
||||
|
||||
fun resume() {
|
||||
// 根据需要实现
|
||||
}
|
||||
|
||||
fun setSpeechRate(rate: Float) {
|
||||
tts?.setSpeechRate(rate)
|
||||
}
|
||||
|
||||
fun setPitch(pitch: Float) {
|
||||
tts?.setPitch(pitch)
|
||||
}
|
||||
|
||||
private fun processPendingQueue() {
|
||||
while (pendingQueue.isNotEmpty()) {
|
||||
speak(pendingQueue.poll())
|
||||
}
|
||||
}
|
||||
|
||||
fun release() {
|
||||
tts?.stop()
|
||||
tts?.shutdown()
|
||||
tts = null
|
||||
isInitialized = false
|
||||
instance = null
|
||||
}
|
||||
}
|
||||
@@ -168,4 +168,28 @@ public class TextViewUtils {
|
||||
public interface OnClickableTextListener {
|
||||
void onClick();
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用正则表达式格式化手机号,中间4位替换为****
|
||||
* @param phone 原始手机号
|
||||
* @return 格式化后的手机号
|
||||
*/
|
||||
public static String formatPhoneNumberWithRegex(String phone) {
|
||||
if (phone == null) {
|
||||
return "";
|
||||
}
|
||||
return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理带区号的手机号,中间4位替换为****
|
||||
* @param phone 原始手机号(可能带区号)
|
||||
* @return 格式化后的手机号
|
||||
*/
|
||||
public static String formatAnyPhone(String phone) {
|
||||
if (phone == null) {
|
||||
return "";
|
||||
}
|
||||
return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ public class TimeUtils {
|
||||
//获取当前日期
|
||||
public static String getCurrentDate2() {
|
||||
Date d = new Date();
|
||||
SimpleDateFormat sf = new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss_SSS");
|
||||
SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日hh时mm分ss秒SSS");
|
||||
return sf.format(d);
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.xscm.moduleutil.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
|
||||
import com.lahm.library.EasyProtectorLib;
|
||||
import com.lahm.library.EmulatorCheckCallback;
|
||||
@@ -50,4 +52,31 @@ public class UtilConfig {
|
||||
public static void setSalt(String salt) {
|
||||
UtilConfig.salt = salt;
|
||||
}
|
||||
|
||||
|
||||
public static int getAttBg(Context context, int attr){
|
||||
// 1. 定义需要获取的自定义属性数组
|
||||
int[] attrs = new int[]{attr};
|
||||
// 2. 从Context的Theme中获取TypedArray(核心:绑定当前主题的属性值)
|
||||
TypedArray ta = context.obtainStyledAttributes(attrs);
|
||||
// 3. 获取attr对应的资源ID,默认值0(无有效资源时返回0)
|
||||
int bgResId = ta.getResourceId(0, 0);
|
||||
// 4. 关键:手动回收TypedArray,释放系统资源,避免内存泄漏
|
||||
ta.recycle();
|
||||
// 5. 有有效资源ID时,设置背景
|
||||
return bgResId;
|
||||
}
|
||||
|
||||
// 新增:解析自定义颜色属性,返回实际颜色码(核心)
|
||||
public static int getAttrColor(Context context, int colorAttrId) {
|
||||
if (context == null) {
|
||||
return Color.BLACK; // 上下文为空时返回默认黑色,可自定义
|
||||
}
|
||||
// 从主题中获取TypedArray,解析颜色属性
|
||||
TypedArray ta = context.obtainStyledAttributes(new int[]{colorAttrId});
|
||||
// getColor(索引, 默认颜色):直接返回十六进制颜色码,适配setTextColor
|
||||
int color = ta.getColor(0, Color.BLACK);
|
||||
ta.recycle(); // 必须回收,避免内存泄漏
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.voice.lib_base.ext
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.lang.reflect.ParameterizedType
|
||||
|
||||
/**
|
||||
* 作者 : QIngNing
|
||||
* 时间 : 2021/12/21
|
||||
* 描述 :
|
||||
*/
|
||||
|
||||
@JvmName("inflateWithGeneric")
|
||||
fun <VB : ViewBinding> AppCompatActivity.inflateBindingWithGeneric(layoutInflater: LayoutInflater): VB =
|
||||
withGenericBindingClass<VB>(this) { clazz ->
|
||||
clazz.getMethod("inflate", LayoutInflater::class.java).invoke(null, layoutInflater) as VB
|
||||
}.also { binding ->
|
||||
if (binding is ViewDataBinding) {
|
||||
binding.lifecycleOwner = this
|
||||
}
|
||||
}
|
||||
|
||||
@JvmName("inflateWithGeneric")
|
||||
fun <VB : ViewBinding> Fragment.inflateBindingWithGeneric(layoutInflater: LayoutInflater, parent: ViewGroup?, attachToParent: Boolean): VB =
|
||||
withGenericBindingClass<VB>(this) { clazz ->
|
||||
clazz.getMethod("inflate", LayoutInflater::class.java, ViewGroup::class.java, Boolean::class.java)
|
||||
.invoke(null, layoutInflater, parent, attachToParent) as VB
|
||||
}.also { binding ->
|
||||
if (binding is ViewDataBinding) {
|
||||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
}
|
||||
}
|
||||
|
||||
private fun <VB : ViewBinding> withGenericBindingClass(any: Any, block: (Class<VB>) -> VB): VB {
|
||||
var genericSuperclass = any.javaClass.genericSuperclass
|
||||
var superclass = any.javaClass.superclass
|
||||
while (superclass != null) {
|
||||
if (genericSuperclass is ParameterizedType) {
|
||||
try {
|
||||
return block.invoke(genericSuperclass.actualTypeArguments[0] as Class<VB>)
|
||||
|
||||
} catch (e: NoSuchMethodException) {
|
||||
} catch (e: ClassCastException) {
|
||||
} catch (e: InvocationTargetException) {
|
||||
throw e.targetException
|
||||
}
|
||||
}
|
||||
genericSuperclass = superclass.genericSuperclass
|
||||
superclass = superclass.superclass
|
||||
}
|
||||
throw IllegalArgumentException("There is no generic of ViewBinding.")
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import android.content.SharedPreferences;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ConfigUtils {
|
||||
|
||||
@@ -74,8 +75,11 @@ public class ConfigUtils {
|
||||
*/
|
||||
|
||||
public String findStringByKey(String key) {
|
||||
if (data_list==null){
|
||||
data_list = new HashMap<String, Object>();
|
||||
}
|
||||
if (data_list.containsKey(key))
|
||||
return data_list.get(key).toString();
|
||||
return data_list.get(key)!=null?data_list.get(key).toString():"";
|
||||
else
|
||||
return sp.getString(key, null);
|
||||
}
|
||||
|
||||
@@ -15,10 +15,52 @@ public enum EnvironmentEnum {
|
||||
1600096860,
|
||||
"3e8f3add448d4692bc1d04c75ffe801b",
|
||||
//"tcp://1.13.101.98",
|
||||
"tcp://1.13.20.30",
|
||||
// "tcp://1.13.20.30",
|
||||
"tcp://yushengapi.qxyushen.top",
|
||||
// "https://vespa.qxyushen.top/h5",
|
||||
"https://yushengapi.qxyushen.top/h5",
|
||||
0),
|
||||
// PRODUCTION(//预测版本
|
||||
// //"https://vespa.qxyushen.top/",
|
||||
// "https://vsyusheng.qxhs.xyz/", //这是要进行正式服测试的地址
|
||||
//// "https://yushengapi.qxyushen.top/",
|
||||
// "KvNmqZc+VMzO4CfGMd5zmG6w6OFwpFO/19TwXUWfHDOBgmnl9DgIuE+kbrjNNnxqhtP3pH7bBrnSaSeFtunr72q6sgpLsfuswcUroMvz2slaTBcNzCaLi+GSnM3gB/GdO47mwLdk+iYBTvPUOCIuT608Z29z09w+vPeUDoMCHJBGXu6uh7Nj6PtV1dfGoUvByk1ZF0WYVjIqKDcb3tXY4jonFh3XAWhzMy8xKwN6F2nuK2IcdIwaSPsvuMZmhatP6f9kOE+vnfweyCHS3RxiG474WIoZGJM8omrl3/pOVqE=",
|
||||
// "https://oss-cn-beijing.aliyuncs.com/",
|
||||
// "LTAI5tKgrfcFQxH46ZwWYgFW",
|
||||
// "ZOjTqAJmUL563EKFKySrUwAHtx4hKt",
|
||||
// "midi01",
|
||||
// "https://midi01.oss-cn-beijing.aliyuncs.com/",
|
||||
// "wxc7681513be9f926b",
|
||||
//// 1600096860,
|
||||
// 1600096890,//这是要进行正式服测试的地址
|
||||
// "3e8f3add448d4692bc1d04c75ffe801b",
|
||||
// //"tcp://1.13.101.98",
|
||||
//// "tcp://1.13.20.30",
|
||||
//// "tcp://yushengapi.qxyushen.top",
|
||||
// "tcp://vsyusheng.qxhs.xyz", //这是要进行正式服测试的地址
|
||||
// // "https://vespa.qxyushen.top/h5",
|
||||
// "https://vsyusheng.qxhs.xyz/h5",
|
||||
//// "https://yushengapi.qxyushen.top/h5",
|
||||
// 0),
|
||||
Auxiliary(//辅助生产环境
|
||||
//"https://vespa.qxyushen.top/",
|
||||
"https://details.qxhs.xyz/",
|
||||
"KvNmqZc+VMzO4CfGMd5zmG6w6OFwpFO/19TwXUWfHDOBgmnl9DgIuE+kbrjNNnxqhtP3pH7bBrnSaSeFtunr72q6sgpLsfuswcUroMvz2slaTBcNzCaLi+GSnM3gB/GdO47mwLdk+iYBTvPUOCIuT608Z29z09w+vPeUDoMCHJBGXu6uh7Nj6PtV1dfGoUvByk1ZF0WYVjIqKDcb3tXY4jonFh3XAWhzMy8xKwN6F2nuK2IcdIwaSPsvuMZmhatP6f9kOE+vnfweyCHS3RxiG474WIoZGJM8omrl3/pOVqE=",
|
||||
"https://oss-cn-beijing.aliyuncs.com/",
|
||||
"LTAI5tKgrfcFQxH46ZwWYgFW",
|
||||
"ZOjTqAJmUL563EKFKySrUwAHtx4hKt",
|
||||
"midi01",
|
||||
"https://midi01.oss-cn-beijing.aliyuncs.com/",
|
||||
"wxc7681513be9f926b",
|
||||
1600096860,
|
||||
"3e8f3add448d4692bc1d04c75ffe801b",
|
||||
//"tcp://1.13.101.98",
|
||||
// "tcp://1.13.20.30",
|
||||
"tcp://details.qxhs.xyz",
|
||||
// "https://vespa.qxyushen.top/h5",
|
||||
"https://details.qxhs.xyz/h5",
|
||||
0),
|
||||
|
||||
TEST(//测试环境
|
||||
"https://test.vespa.qxyushen.top/",
|
||||
"6rdWuz058oq5OahdbFiGEybUcdahd12J83L34Uc7MrPIrxtFG+rXiwDvRcqNvjwbClbbmvMrmxKVkIysFByBsl0Qe9kqd2w8T/nhK5G6eXXlk2V9AjYCieIU+jRnjZBB+Cfechr6rCGJ2aeBARIsXcRPW7wm9WFK9euh5T+v6Pyte68yNaNdcYCll3+U4/uCEog7HygCnMIbAU+kqoPdmn2H+51YOHW+VsnsHd4w1+I3f8Tt0xLIXGM4GWnQueZ5GR46GTWiSYMy8dCIh9SPIMRyC91GosVcfGPMJSdcXqc=",
|
||||
@@ -30,7 +72,8 @@ public enum EnvironmentEnum {
|
||||
"wxc7681513be9f926b",
|
||||
1600096890,
|
||||
"02f7339ec98947deaeab173599891932",
|
||||
"tcp://1.13.181.248",
|
||||
// "tcp://1.13.181.248",
|
||||
"tcp://test.vespa.qxyushen.top",
|
||||
"https://test.vespa.qxyushen.top/h5",
|
||||
1);
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.io.IOException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.Connection;
|
||||
@@ -54,24 +55,25 @@ public class DataLoggingInterceptor implements Interceptor {
|
||||
|
||||
logger.reset();
|
||||
logger.log(sLogStartFlag);
|
||||
logger.log(sFormatLine);
|
||||
// logger.log("2\n"+sFormatLine);
|
||||
|
||||
RequestBody requestBody = request.body();
|
||||
boolean hasRequestBody = requestBody != null;
|
||||
|
||||
Connection connection = chain.connection();
|
||||
Protocol protocol = connection != null ? connection.protocol() : Protocol.HTTP_1_1;
|
||||
String requestStartMessage = request.method() + " " + request.url() + " " + protocol;
|
||||
logger.log(requestStartMessage);
|
||||
// request.url().encodedPath() 这是只展示最后的url地址,没有带有前面的https对应的域名,只是展示路径
|
||||
String requestStartMessage = request.method() + " " + Arrays.toString(request.url().encodedPath().split("/api/")) + " " + protocol;
|
||||
// logger.log("3\n"+requestStartMessage);
|
||||
|
||||
if (hasRequestBody) {
|
||||
// Request body headers are only present when installed as a network interceptor. Force
|
||||
// them to be included (when available) so there values are known.
|
||||
if (requestBody.contentType() != null) {
|
||||
logger.log("Content-Type: " + requestBody.contentType());
|
||||
// logger.log("4\n"+ "Content-Type: " + requestBody.contentType());
|
||||
}
|
||||
if (requestBody.contentLength() != -1) {
|
||||
logger.log("Content-Length: " + requestBody.contentLength());
|
||||
// logger.log("5\n"+"Content-Length: " + requestBody.contentLength());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,14 +82,14 @@ public class DataLoggingInterceptor implements Interceptor {
|
||||
String name = rHeaders.name(i);
|
||||
// Skip headers from the request body as they are explicitly logged above.
|
||||
if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
|
||||
logger.log(name + ": " + rHeaders.value(i));
|
||||
// logger.log("6\n"+name + ": " + rHeaders.value(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasRequestBody) {
|
||||
logger.log("END " + request.method());
|
||||
// logger.log("7\n"+"END " + request.method());
|
||||
} else if (bodyEncoded(request.headers())) {
|
||||
logger.log("END " + request.method() + " (encoded body omitted)");
|
||||
// logger.log("8\n"+"END " + request.method() + " (encoded body omitted)");
|
||||
} else {
|
||||
Buffer buffer = new Buffer();
|
||||
requestBody.writeTo(buffer);
|
||||
@@ -99,35 +101,35 @@ public class DataLoggingInterceptor implements Interceptor {
|
||||
}
|
||||
|
||||
if (charset != null) {
|
||||
logger.log(sFormatLine);
|
||||
// logger.log("9\n"+sFormatLine);
|
||||
if (isPlaintext(buffer)) {
|
||||
try {
|
||||
String requestStr = URLDecoder.decode(buffer.readString(charset), "UTF-8");
|
||||
String[] strs = requestStr.split("&");
|
||||
for (String str : strs) {
|
||||
logger.log(str);
|
||||
// logger.log("10\n"+str);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(buffer.readString(charset));
|
||||
logger.log("11\n"+buffer.readString(charset));
|
||||
}
|
||||
logger.log("END " + request.method()
|
||||
+ " (" + requestBody.contentLength() + "-byte body)");
|
||||
// logger.log("12\n"+"END " + request.method()
|
||||
// + " (" + requestBody.contentLength() + "-byte body)");
|
||||
} else {
|
||||
logger.log("END " + request.method() + " (binary "
|
||||
+ requestBody.contentLength() + "-byte body omitted)");
|
||||
// logger.log("13\n"+"END " + request.method() + " (binary "
|
||||
// + requestBody.contentLength() + "-byte body omitted)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.log(sFormatLine);
|
||||
// logger.log("14\n"+sFormatLine);
|
||||
|
||||
long startNs = System.nanoTime();
|
||||
Response response;
|
||||
try {
|
||||
response = chain.proceed(request);
|
||||
} catch (Exception e) {
|
||||
logger.log("HTTP FAILED: " + e);
|
||||
logger.log(sLogEndFlag);
|
||||
logger.log("15\n"+"HTTP FAILED: " + e);
|
||||
// logger.log(sLogEndFlag);
|
||||
throw e;
|
||||
}
|
||||
|
||||
@@ -136,21 +138,19 @@ public class DataLoggingInterceptor implements Interceptor {
|
||||
if (responseBody != null) {
|
||||
long contentLength = responseBody.contentLength();
|
||||
String bodySize = contentLength != -1 ? contentLength + "-byte" : "unknown-length";
|
||||
// logger.log(response.code() + " " + response.message() + " "
|
||||
// + response.request().url() + " (" + tookMs + "ms)");
|
||||
|
||||
logger.log(response.code() + " " + response.message() + " "
|
||||
+ response.request().url() + " → " + response.networkResponse().request().url() + " (" + tookMs + "ms)");
|
||||
logger.log("17\n"+response.code() + " " + response.message() + " "
|
||||
+ Arrays.toString(response.request().url().encodedPath().split("/api/")) + " → " + Arrays.toString(response.networkResponse().request().url().encodedPath().split("/api/")) + " (" + tookMs + "ms)");
|
||||
|
||||
Headers headers = response.headers();
|
||||
for (int i = 0, count = headers.size(); i < count; i++) {
|
||||
logger.log(headers.name(i) + ": " + headers.value(i));
|
||||
}
|
||||
// Headers headers = response.headers();
|
||||
// for (int i = 0, count = headers.size(); i < count; i++) {
|
||||
// logger.log("18\n"+headers.name(i) + ": " + headers.value(i));
|
||||
// }
|
||||
|
||||
if (!HttpHeaders.hasBody(response)) {
|
||||
logger.log("END HTTP");
|
||||
// logger.log("19\n"+"END HTTP");
|
||||
} else if (bodyEncoded(response.headers())) {
|
||||
logger.log("END HTTP (encoded body omitted)");
|
||||
// logger.log("20\n"+"END HTTP (encoded body omitted)");
|
||||
} else {
|
||||
BufferedSource source = responseBody.source();
|
||||
if (source.isOpen()) {
|
||||
@@ -164,25 +164,26 @@ public class DataLoggingInterceptor implements Interceptor {
|
||||
}
|
||||
|
||||
if (!isPlaintext(buffer)) {
|
||||
logger.log("END HTTP (binary " + buffer.size() + "-byte body omitted)");
|
||||
logger.log(sFormatLine);
|
||||
// logger.log("21\n"+"END HTTP (binary " + buffer.size() + "-byte body omitted)");
|
||||
// logger.log("22\n"+sFormatLine);
|
||||
logger.log(sLogEndFlag);
|
||||
return response;
|
||||
}
|
||||
|
||||
if (contentLength != 0 && charset != null) {
|
||||
logger.log(sFormatLine);
|
||||
logger.log(buffer.clone().readString(charset));
|
||||
// logger.log("24\n"+sFormatLine);
|
||||
//这是展示返回的数据日志
|
||||
// logger.log(buffer.clone().readString(charset));
|
||||
}
|
||||
|
||||
logger.log("END HTTP (" + buffer.size() + "-byte body)");
|
||||
// logger.log("25\n"+"END HTTP (" + buffer.size() + "-byte body)");
|
||||
} else {
|
||||
logger.log("END HTTP");
|
||||
// logger.log("26\n"+"END HTTP");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.log(sFormatLine);
|
||||
logger.log("27\n"+sFormatLine);
|
||||
logger.log(sLogEndFlag);
|
||||
|
||||
return response;
|
||||
|
||||
@@ -178,7 +178,7 @@ public class RoomCPView extends FrameLayout {
|
||||
|
||||
|
||||
// 启动头像上下浮动动画
|
||||
// startAvatarFloatAnimation();
|
||||
startAvatarFloatAnimation();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -193,11 +193,21 @@ public class RoomCPView extends FrameLayout {
|
||||
LogUtils.e("onFailed", s);
|
||||
// 确保所有UI操作在主线程中执行
|
||||
post(() -> {
|
||||
// 动画失败,隐藏视图
|
||||
setVisibility(View.GONE);
|
||||
anim_cp.setVisibility(View.GONE);
|
||||
// 继续播放下一个
|
||||
loadStartAnimation();
|
||||
if (anim_cp != null) {
|
||||
// 停止头像动画
|
||||
stopAvatarAnimation();
|
||||
|
||||
// 隐藏动画视图和头像
|
||||
anim_cp.setVisibility(View.GONE);
|
||||
avatarContainer1.setVisibility(View.GONE);
|
||||
|
||||
if (isOnece) {
|
||||
return;
|
||||
}
|
||||
// 通知播放完成
|
||||
notifyPlaybackComplete();
|
||||
loadStartAnimation();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -274,11 +284,15 @@ public class RoomCPView extends FrameLayout {
|
||||
post(() -> {
|
||||
// 设置MP4动画文件
|
||||
currPlayPath = localPath;
|
||||
// 启动从底部弹起动画
|
||||
startBottomUpAnimation();
|
||||
|
||||
// 开始播放动画
|
||||
anim_cp.setLoop(1);
|
||||
|
||||
startBottomUpAnimation();
|
||||
|
||||
setVisibility(View.VISIBLE);
|
||||
anim_cp.setVisibility(View.VISIBLE);
|
||||
avatarContainer1.setVisibility(VISIBLE);
|
||||
anim_cp.startPlay(new File(currPlayPath));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -717,11 +731,10 @@ public class RoomCPView extends FrameLayout {
|
||||
bottomUpAnimation.setAnimationListener(new Animation.AnimationListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animation animation) {
|
||||
setVisibility(View.VISIBLE);
|
||||
anim_cp.setVisibility(View.VISIBLE);
|
||||
avatarContainer1.setVisibility(VISIBLE);
|
||||
|
||||
anim_cp.startPlay(new File(currPlayPath));
|
||||
// setVisibility(View.VISIBLE);
|
||||
// anim_cp.setVisibility(View.VISIBLE);
|
||||
// avatarContainer1.setVisibility(VISIBLE);
|
||||
// anim_cp.startPlay(new File(currPlayPath));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -752,12 +765,31 @@ public class RoomCPView extends FrameLayout {
|
||||
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
|
||||
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, -0.01f);
|
||||
avatarsFloatUp.setDuration(900); // 增加动画持续时间,使动画更平滑
|
||||
avatarsFloatUp.setRepeatCount(Animation.INFINITE);
|
||||
avatarsFloatUp.setRepeatCount(10);
|
||||
avatarsFloatUp.setRepeatMode(Animation.REVERSE);
|
||||
|
||||
avatarsAnimationSet.addAnimation(avatarsFloatUp);
|
||||
avatarsParentContainer.startAnimation(avatarsAnimationSet);
|
||||
|
||||
// 动画结束后重置位置
|
||||
avatarsAnimationSet.setAnimationListener(new Animation.AnimationListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animation animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animation animation) {
|
||||
if (avatarContainer1.getVisibility() == View.VISIBLE) {
|
||||
avatarContainer1.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animation animation) {
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.xscm.moduleutil.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.xscm.moduleutil.R;
|
||||
|
||||
/**
|
||||
* 项目名称:羽声语音
|
||||
* 时间:2026/1/4 16:09
|
||||
* 用途:自定义组件:购买数量,带减少增加按钮
|
||||
*/
|
||||
public class AmountView extends LinearLayout implements View.OnClickListener, TextWatcher {
|
||||
|
||||
private static final String TAG = "AmountView";
|
||||
private int amount = 1; //购买数量
|
||||
private int goods_storage = Integer.MAX_VALUE; //商品库存
|
||||
|
||||
private OnAmountChangeListener mListener;
|
||||
|
||||
private EditText etAmount;
|
||||
private Button btnDecrease;
|
||||
private Button btnIncrease;
|
||||
|
||||
public AmountView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public AmountView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
LayoutInflater.from(context).inflate(R.layout.view_amount, this);
|
||||
etAmount = (EditText) findViewById(R.id.etAmount);
|
||||
btnDecrease = (Button) findViewById(R.id.btnDecrease);
|
||||
btnIncrease = (Button) findViewById(R.id.btnIncrease);
|
||||
btnDecrease.setOnClickListener(this);
|
||||
btnIncrease.setOnClickListener(this);
|
||||
etAmount.addTextChangedListener(this);
|
||||
|
||||
TypedArray obtainStyledAttributes = getContext().obtainStyledAttributes(attrs, R.styleable.AmountView);
|
||||
int btnWidth = obtainStyledAttributes.getDimensionPixelSize(R.styleable.AmountView_btnWidth, LayoutParams.WRAP_CONTENT);
|
||||
int tvWidth = obtainStyledAttributes.getDimensionPixelSize(R.styleable.AmountView_tvWidth, 80);
|
||||
int tvTextSize = obtainStyledAttributes.getDimensionPixelSize(R.styleable.AmountView_tvTextSize, 0);
|
||||
int btnTextSize = obtainStyledAttributes.getDimensionPixelSize(R.styleable.AmountView_btnTextSize, 0);
|
||||
obtainStyledAttributes.recycle();
|
||||
|
||||
LayoutParams btnParams = new LayoutParams(btnWidth, LayoutParams.MATCH_PARENT);
|
||||
btnDecrease.setLayoutParams(btnParams);
|
||||
btnIncrease.setLayoutParams(btnParams);
|
||||
if (btnTextSize != 0) {
|
||||
btnDecrease.setTextSize(TypedValue.COMPLEX_UNIT_PX, btnTextSize);
|
||||
btnIncrease.setTextSize(TypedValue.COMPLEX_UNIT_PX, btnTextSize);
|
||||
}
|
||||
|
||||
LayoutParams textParams = new LayoutParams(tvWidth, LayoutParams.MATCH_PARENT);
|
||||
etAmount.setLayoutParams(textParams);
|
||||
if (tvTextSize != 0) {
|
||||
etAmount.setTextSize(tvTextSize);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnAmountChangeListener(OnAmountChangeListener onAmountChangeListener) {
|
||||
this.mListener = onAmountChangeListener;
|
||||
}
|
||||
|
||||
public void setGoods_storage(int goods_storage) {
|
||||
this.goods_storage = goods_storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int i = v.getId();
|
||||
if (i == R.id.btnDecrease) {
|
||||
if (amount > 1) {
|
||||
amount--;
|
||||
etAmount.setText(amount + "");
|
||||
}
|
||||
} else if (i == R.id.btnIncrease) {
|
||||
if (amount < goods_storage) {
|
||||
amount++;
|
||||
etAmount.setText(amount + "");
|
||||
}
|
||||
}
|
||||
|
||||
etAmount.clearFocus();
|
||||
|
||||
if (mListener != null) {
|
||||
mListener.onAmountChange(this, amount);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (s.toString().isEmpty())
|
||||
return;
|
||||
amount = Integer.valueOf(s.toString());
|
||||
if (amount > goods_storage) {
|
||||
etAmount.setText(goods_storage + "");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mListener != null) {
|
||||
mListener.onAmountChange(this, amount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface OnAmountChangeListener {
|
||||
void onAmountChange(View view, int amount);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +1,11 @@
|
||||
package com.xscm.moduleutil.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.SoundEffectConstants;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
@@ -16,21 +14,14 @@ import androidx.annotation.Nullable;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
import com.liulishuo.okdownload.DownloadTask;
|
||||
import com.liulishuo.okdownload.core.cause.EndCause;
|
||||
import com.liulishuo.okdownload.core.cause.ResumeFailedCause;
|
||||
import com.liulishuo.okdownload.core.listener.DownloadListener1;
|
||||
import com.liulishuo.okdownload.core.listener.assist.Listener1Assist;
|
||||
import com.opensource.svgaplayer.SVGACallback;
|
||||
import com.opensource.svgaplayer.SVGADrawable;
|
||||
import com.opensource.svgaplayer.SVGADynamicEntity;
|
||||
import com.opensource.svgaplayer.SVGAImageView;
|
||||
import com.opensource.svgaplayer.SVGAParser;
|
||||
import com.opensource.svgaplayer.SVGAVideoEntity;
|
||||
import com.tencent.qgame.animplayer.inter.IAnimListener;
|
||||
import com.xscm.moduleutil.R;
|
||||
import com.xscm.moduleutil.databinding.RoomViewSvgaAnimBinding;
|
||||
import com.xscm.moduleutil.utils.SpUtil;
|
||||
import com.xscm.moduleutil.utils.logger.Logger;
|
||||
|
||||
import java.io.File;
|
||||
@@ -40,11 +31,8 @@ import java.io.InputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
@@ -57,9 +45,9 @@ import okhttp3.ResponseBody;
|
||||
|
||||
|
||||
public class AvatarFrameView extends FrameLayout {
|
||||
private PlaybackManager playbackManager;
|
||||
|
||||
private boolean isMute = false;
|
||||
|
||||
public void setMute(boolean b) {
|
||||
this.isMute = b;
|
||||
}
|
||||
@@ -68,10 +56,7 @@ public class AvatarFrameView extends FrameLayout {
|
||||
|
||||
private RenderType renderType;
|
||||
private SVGAImageView svgaSurface;
|
||||
private SVGAImageView svgaSurface2;
|
||||
private final Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
private int mType;//1:循环播放 2:播放一次停止播放
|
||||
private final BlockingQueue<PlayItem> playQueue = new LinkedBlockingQueue<>();
|
||||
|
||||
private boolean isPlaying = false;
|
||||
// 添加销毁标记
|
||||
@@ -79,8 +64,6 @@ public class AvatarFrameView extends FrameLayout {
|
||||
private static final String TAG = "AvatarFrameView";
|
||||
private RoomViewSvgaAnimBinding mBinding;
|
||||
|
||||
// 内存监控
|
||||
private static final long MAX_MEMORY_THRESHOLD = 300 * 1024 * 1024; // 300MB
|
||||
private static final int MAX_SVGA_CACHE_SIZE = 3;
|
||||
private final Map<String, WeakReference<SVGAVideoEntity>> svgaCache = new LruCache<>(MAX_SVGA_CACHE_SIZE);
|
||||
|
||||
@@ -101,25 +84,10 @@ public class AvatarFrameView extends FrameLayout {
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
// if (isDestroyed) return;
|
||||
// 初始化 ExoPlayer View
|
||||
// playerView = new PlayerView(getContext());
|
||||
// playerView.setUseController(false);
|
||||
// playerView.setVisibility(View.GONE);
|
||||
// addView(playerView);
|
||||
|
||||
// 初始化 SVGA View
|
||||
svgaSurface = new SVGAImageView(getContext());
|
||||
svgaSurface.setVisibility(View.GONE);
|
||||
addView(svgaSurface);
|
||||
|
||||
svgaSurface2 = new SVGAImageView(getContext());
|
||||
svgaSurface2.setVisibility(View.GONE);
|
||||
addView(svgaSurface2);
|
||||
|
||||
// 初始化播放管理器
|
||||
playbackManager = new PlaybackManager(mainHandler);
|
||||
|
||||
}
|
||||
|
||||
private String getFileExtension(String url) {
|
||||
@@ -130,186 +98,51 @@ public class AvatarFrameView extends FrameLayout {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public void playNextFromQueue() {
|
||||
// if (isDestroyed) return;
|
||||
// 确保在主线程中执行
|
||||
// if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
// mainHandler.post(this::playNextFromQueue);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// 检查特效是否开启
|
||||
// if (SpUtil.getOpenEffect() != 1) {
|
||||
// clearQueue();
|
||||
// return;
|
||||
// }
|
||||
// 检查是否可以开始新的播放
|
||||
// if (!playbackManager.canStartNewPlayback()) {
|
||||
// Logger.d("AvatarFrameView", "Max concurrent playbacks reached, waiting...");
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (!isPlaying || !isActuallyPlaying()) {
|
||||
|
||||
|
||||
PlayItem item = playQueue.poll();
|
||||
if (item != null) {
|
||||
// 通知开始播放
|
||||
playbackManager.onStartPlayback();
|
||||
isPlaying = true;
|
||||
|
||||
// 处理播放项目
|
||||
processPlayItem(item);
|
||||
|
||||
} else {
|
||||
isPlaying = false;
|
||||
Logger.d("AvatarFrameView", "Queue is empty, stop playing");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加统一的播放完成处理方法
|
||||
public void onPlaybackComplete() {
|
||||
if (isDestroyed) return;
|
||||
mainHandler.post(() -> {
|
||||
// 再次检查是否已销毁
|
||||
if (isDestroyed) return;
|
||||
|
||||
// // 通知播放管理器播放完成
|
||||
// playbackManager.onFinishPlayback();
|
||||
|
||||
// 重置播放状态
|
||||
isPlaying = false;
|
||||
|
||||
// 内存清理检查
|
||||
// if (playQueue.size() % 5 == 0) {
|
||||
// performLightMemoryCleanup();
|
||||
// }
|
||||
// 继续处理队列中的下一个项目
|
||||
playNextFromQueue();
|
||||
});
|
||||
public void setSource(String url, int type2) {
|
||||
// 添加到播放队列
|
||||
PlayItem item = new PlayItem(url, type2);
|
||||
processPlayItem(item);
|
||||
Logger.d("AvatarFrameView", "Added to queue, queue size: url: " + url);
|
||||
}
|
||||
|
||||
private void processPlayItem(PlayItem item) {
|
||||
try {
|
||||
// clearPrevious();
|
||||
|
||||
String ext = getFileExtension(item.url);
|
||||
if ("svga".equalsIgnoreCase(ext)) {
|
||||
mainHandler.post(() -> {
|
||||
renderType = RenderType.SVGA;
|
||||
mType = item.type;
|
||||
if (mBinding != null && mBinding.playView != null) {
|
||||
mBinding.playView.setVisibility(View.GONE);
|
||||
}
|
||||
loadSVGA(item.url);
|
||||
});
|
||||
renderType = RenderType.SVGA;
|
||||
mType = item.type;
|
||||
if (mBinding != null) {
|
||||
mBinding.playView.setVisibility(View.GONE);
|
||||
}
|
||||
loadSVGA(item.url);
|
||||
} else if ("mp4".equalsIgnoreCase(ext)) {
|
||||
mainHandler.post(() -> {
|
||||
renderType = RenderType.MP4;
|
||||
mType = item.type;
|
||||
if (mBinding != null && mBinding.playView != null) {
|
||||
mBinding.playView.setVisibility(View.VISIBLE);
|
||||
|
||||
downloadAndPlayMp4(item.url);
|
||||
}else {
|
||||
mBinding = DataBindingUtil.inflate(LayoutInflater.from(getContext()), R.layout.room_view_svga_anim, this, true);
|
||||
mBinding.playView.setVisibility(View.VISIBLE);
|
||||
downloadAndPlayMp4(item.url);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 不支持的格式,直接完成
|
||||
handlePlaybackComplete();
|
||||
renderType = RenderType.MP4;
|
||||
mType = item.type;
|
||||
if (mBinding != null) {
|
||||
mBinding.playView.setVisibility(View.VISIBLE);
|
||||
downloadAndPlayMp4(item.url);
|
||||
} else {
|
||||
mBinding = DataBindingUtil.inflate(LayoutInflater.from(getContext()), R.layout.room_view_svga_anim, this, true);
|
||||
mBinding.playView.setVisibility(View.VISIBLE);
|
||||
downloadAndPlayMp4(item.url);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtils.e(TAG, "Error processing play item: " + e.getMessage());
|
||||
handlePlaybackComplete();
|
||||
}
|
||||
}
|
||||
|
||||
// 添加实际播放状态检查方法
|
||||
private boolean isActuallyPlaying() {
|
||||
if (renderType == RenderType.SVGA && svgaSurface != null) {
|
||||
return svgaSurface.isAnimating();
|
||||
} else if (renderType == RenderType.MP4 && mBinding != null) {
|
||||
// 检查播放器状态
|
||||
return mBinding.playView.isRunning();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPlaying() {
|
||||
if (mBinding != null && mBinding.playView != null) {
|
||||
if (mBinding != null) {
|
||||
return mBinding.playView.isRunning();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// 在 AvatarFrameView 类中添加以下代码
|
||||
|
||||
private static final int MAX_CONCURRENT_PROCESSING = 3; // 同时处理的最大动画数
|
||||
private static final int PROCESSING_DELAY = 100; // 处理间隔(毫秒)
|
||||
private int currentProcessingCount = 0;
|
||||
|
||||
public void setSource(String url, int type2) {
|
||||
// if (isDestroyed) return;
|
||||
// 确保在主线程中执行
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
mainHandler.post(() -> setSource(url, type2));
|
||||
return;
|
||||
}
|
||||
|
||||
// 添加到播放队列
|
||||
playQueue.add(new PlayItem(url, type2));
|
||||
Logger.d("AvatarFrameView", "Added to queue, queue size: " + playQueue.size() + ", url: " + url);
|
||||
|
||||
if (type2 == 3 || type2 == 1) {
|
||||
// playNextFromQueue();
|
||||
loadSVGA(url);
|
||||
} else {
|
||||
|
||||
// 如果当前没有在播放,则开始播放
|
||||
if (!isPlaying || !isActuallyPlaying()) {
|
||||
playNextFromQueue();
|
||||
}
|
||||
}
|
||||
Logger.d("AvatarFrameView", "Added to queue, queue size: " + playQueue.size() + ", url: " + url);
|
||||
}
|
||||
|
||||
private void smartCheckAndStartPlayback() {
|
||||
// 检查是否可以开始新的播放任务
|
||||
if (!playQueue.isEmpty() &&
|
||||
(!isPlaying || !isActuallyPlaying()) &&
|
||||
currentProcessingCount < MAX_CONCURRENT_PROCESSING) {
|
||||
|
||||
currentProcessingCount++;
|
||||
playNextFromQueue();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAndStartPlayback() {
|
||||
// 如果队列不为空且当前没有在播放,则开始播放
|
||||
if (!playQueue.isEmpty() && (!isPlaying || !isActuallyPlaying())) {
|
||||
playNextFromQueue();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMemoryLow() {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
|
||||
long maxMemory = runtime.maxMemory();
|
||||
double memoryUsage = (double) usedMemory / maxMemory;
|
||||
|
||||
// 内存使用超过80%或绝对使用量超过阈值
|
||||
return memoryUsage > 0.8 || usedMemory > MAX_MEMORY_THRESHOLD;
|
||||
}
|
||||
|
||||
|
||||
boolean isTxk = false;
|
||||
|
||||
public void downloadAndPlayMp4(String url) {
|
||||
|
||||
// 提取文件名
|
||||
String fileName = url.substring(url.lastIndexOf("/"));
|
||||
String filePath = getContext().getCacheDir().getAbsolutePath() + fileName;
|
||||
@@ -330,12 +163,6 @@ public class AvatarFrameView extends FrameLayout {
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e) {
|
||||
LogUtils.e("MP4下载失败: " + e.toString());
|
||||
mainHandler.post(() -> {
|
||||
// 检查是否已销毁
|
||||
if (!isDestroyed) {
|
||||
onPlaybackComplete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 更简单的优化版本
|
||||
@@ -371,63 +198,36 @@ public class AvatarFrameView extends FrameLayout {
|
||||
|
||||
fos.flush();
|
||||
isTxk = true;
|
||||
mainHandler.post(() -> {
|
||||
// 关键:在执行UI操作前再次检查是否已销毁
|
||||
if (downloadedFile.exists()) {
|
||||
LogUtils.d("@@@@Thread", Thread.currentThread().getName());
|
||||
playMp4File(downloadedFile); // 使用正确的文件引用
|
||||
} else {
|
||||
LogUtils.w(TAG, "View destroyed or file not exist after download");
|
||||
onPlaybackComplete();
|
||||
}
|
||||
});
|
||||
// 关键:在执行UI操作前再次检查是否已销毁
|
||||
if (downloadedFile.exists()) {
|
||||
LogUtils.d("@@@@Thread", Thread.currentThread().getName());
|
||||
playMp4File(downloadedFile); // 使用正确的文件引用
|
||||
} else {
|
||||
LogUtils.w(TAG, "View destroyed or file not exist after download");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LogUtils.e("MP4文件保存失败: " + e.getMessage());
|
||||
mainHandler.post(() -> {
|
||||
if (!isDestroyed) {
|
||||
onPlaybackComplete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
mainHandler.post(() -> {
|
||||
if (!isDestroyed) {
|
||||
onPlaybackComplete();
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtils.e("MP4文件保存失败: " + e.getMessage());
|
||||
mainHandler.post(() -> {
|
||||
if (!isDestroyed) {
|
||||
onPlaybackComplete();
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("MP4下载响应失败");
|
||||
mainHandler.post(() -> {
|
||||
if (!isDestroyed) {
|
||||
onPlaybackComplete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
isTxk = true;
|
||||
LogUtils.e("有缓存");
|
||||
mainHandler.post(() -> {
|
||||
// 检查是否已销毁
|
||||
if (file.exists()) {
|
||||
LogUtils.e("有缓存:"+file.exists()+"===="+file.getAbsolutePath());
|
||||
playMp4File(file);
|
||||
} else {
|
||||
LogUtils.w(TAG, "有缓存2222222222222");
|
||||
}
|
||||
});
|
||||
// 检查是否已销毁
|
||||
if (file.exists()) {
|
||||
LogUtils.e("有缓存:" + file.exists() + "====" + file.getAbsolutePath());
|
||||
playMp4File(file);
|
||||
} else {
|
||||
LogUtils.w(TAG, "有缓存2222222222222");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,13 +236,11 @@ public class AvatarFrameView extends FrameLayout {
|
||||
// 双重检查确保组件未被销毁
|
||||
if (isDestroyed) {
|
||||
LogUtils.w(TAG, "Attempt to play MP4 file after view destroyed");
|
||||
onPlaybackComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mBinding == null || mBinding.playView == null) {
|
||||
if (mBinding == null) {
|
||||
LogUtils.w(TAG, "PlayView is null");
|
||||
onPlaybackComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -453,27 +251,23 @@ public class AvatarFrameView extends FrameLayout {
|
||||
} else {
|
||||
mBinding.playView.setLoop(1); // 播放一次
|
||||
}
|
||||
mBinding.playView.setMute(isMute);
|
||||
mBinding.playView.setMute(isMute);
|
||||
// 开始播放前检查视图状态
|
||||
if (!isDestroyed && mBinding != null && mBinding.playView != null) {
|
||||
mBinding.playView.startPlay(file);
|
||||
} else {
|
||||
LogUtils.w(TAG, "View was destroyed before MP4 playback started");
|
||||
onPlaybackComplete();
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("播放MP4文件出错: 文件不存在或已损坏");
|
||||
onPlaybackComplete();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtils.e("播放MP4文件出错: " + e.getMessage());
|
||||
onPlaybackComplete();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSVGAComplete(SVGAVideoEntity videoItem, String url) {
|
||||
if (svgaSurface == null) {
|
||||
onPlaybackComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -496,7 +290,6 @@ public class AvatarFrameView extends FrameLayout {
|
||||
svgaSurface.stopAnimation();
|
||||
svgaSurface.clearAnimation();
|
||||
svgaSurface.setImageDrawable(null);
|
||||
onPlaybackComplete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,11 +299,8 @@ public class AvatarFrameView extends FrameLayout {
|
||||
|
||||
@Override
|
||||
public void onFinished() {
|
||||
// if (isDestroyed) return;
|
||||
if (mType == 1) { // 循环播放
|
||||
// 继续循环播放
|
||||
} else {
|
||||
onPlaybackComplete();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -523,10 +313,6 @@ public class AvatarFrameView extends FrameLayout {
|
||||
svgaSurface.startAnimation();
|
||||
} catch (Exception e) {
|
||||
LogUtils.e(TAG, "Error handling SVGA completion: " + e.getMessage());
|
||||
// isPlaying = false;
|
||||
// playNextFromQueue();
|
||||
|
||||
handlePlaybackComplete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,13 +322,15 @@ public class AvatarFrameView extends FrameLayout {
|
||||
svgaSurface.clearAnimation();
|
||||
svgaSurface.setImageDrawable(null);
|
||||
}
|
||||
if (svgaSurface2 != null) {
|
||||
svgaSurface2.stopAnimation();
|
||||
svgaSurface2.clearAnimation();
|
||||
svgaSurface.setImageDrawable(null);
|
||||
}
|
||||
// 增加空值检查
|
||||
if (mBinding != null && mBinding.playView != null) {
|
||||
if (mBinding != null) {
|
||||
mBinding.playView.stopPlay();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopPlay(){
|
||||
// 增加空值检查
|
||||
if (mBinding != null && mBinding.playView.isRunning()) {
|
||||
mBinding.playView.stopPlay();
|
||||
}
|
||||
}
|
||||
@@ -566,16 +354,7 @@ public class AvatarFrameView extends FrameLayout {
|
||||
|
||||
@Override
|
||||
public void onFinished() {
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
mainHandler.post(() -> {
|
||||
isPlaying = false;
|
||||
// 添加延迟确保状态更新
|
||||
mainHandler.postDelayed(AvatarFrameView.this::playNextFromQueue, 50);
|
||||
});
|
||||
} else {
|
||||
isPlaying = false;
|
||||
mainHandler.postDelayed(AvatarFrameView.this::playNextFromQueue, 50);
|
||||
}
|
||||
isPlaying = false;
|
||||
}
|
||||
});
|
||||
// 设置循环次数
|
||||
@@ -588,21 +367,16 @@ public class AvatarFrameView extends FrameLayout {
|
||||
} catch (Exception e) {
|
||||
LogUtils.e(TAG, "Error playing cached SVGA: " + e.getMessage());
|
||||
isPlaying = false;
|
||||
mainHandler.postDelayed(AvatarFrameView.this::playNextFromQueue, 50);
|
||||
// playNextFromQueue();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadNewSVGA(String url) {
|
||||
|
||||
try {
|
||||
new SVGAParser(getContext()).parse(new URL(url), new SVGAParser.ParseCompletion() {
|
||||
@Override
|
||||
public void onComplete(SVGAVideoEntity videoItem) {
|
||||
// if (isDestroyed) return;
|
||||
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
mainHandler.post(() -> handleSVGAComplete(videoItem, url));
|
||||
handleSVGAComplete(videoItem, url);
|
||||
} else {
|
||||
handleSVGAComplete(videoItem, url);
|
||||
}
|
||||
@@ -610,32 +384,16 @@ public class AvatarFrameView extends FrameLayout {
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
// if (isDestroyed) return;
|
||||
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
mainHandler.post(() -> {
|
||||
isPlaying = false;
|
||||
playNextFromQueue();
|
||||
});
|
||||
} else {
|
||||
isPlaying = false;
|
||||
playNextFromQueue();
|
||||
}
|
||||
isPlaying = false;
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
LogUtils.e(TAG, "Error parsing SVGA: " + e.getMessage());
|
||||
isPlaying = false;
|
||||
playNextFromQueue();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSVGA(String url) {
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
mainHandler.post(() -> loadSVGA(url));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
svgaSurface.setVisibility(View.VISIBLE);
|
||||
|
||||
@@ -646,6 +404,7 @@ public class AvatarFrameView extends FrameLayout {
|
||||
if (cachedEntity != null) {
|
||||
// 使用缓存的实体
|
||||
playCachedSVGA(cachedEntity);
|
||||
return;
|
||||
} else {
|
||||
// 加载新的SVGA
|
||||
loadNewSVGA(url);
|
||||
@@ -653,52 +412,49 @@ public class AvatarFrameView extends FrameLayout {
|
||||
} catch (Exception e) {
|
||||
LogUtils.e(TAG, "Error loading SVGA: " + e.getMessage());
|
||||
isPlaying = false;
|
||||
playNextFromQueue();
|
||||
}
|
||||
|
||||
svgaSurface.setVisibility(View.VISIBLE);
|
||||
try {
|
||||
new SVGAParser(getContext()).parse(new URL(url), new SVGAParser.ParseCompletion() {
|
||||
@Override
|
||||
public void onComplete(SVGAVideoEntity videoItem) {
|
||||
SVGADrawable drawable = new SVGADrawable(videoItem, new SVGADynamicEntity());
|
||||
svgaSurface.setImageDrawable(drawable);
|
||||
svgaSurface.setCallback(new SVGACallback() {
|
||||
|
||||
@Override
|
||||
public void onStep(int i, double v) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeat() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinished() {
|
||||
isPlaying = false;
|
||||
playNextFromQueue();
|
||||
}
|
||||
});
|
||||
|
||||
svgaSurface.startAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
isPlaying = false;
|
||||
playNextFromQueue();
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// svgaSurface.setVisibility(View.VISIBLE);
|
||||
// try {
|
||||
// new SVGAParser(getContext()).parse(new URL(url), new SVGAParser.ParseCompletion() {
|
||||
// @Override
|
||||
// public void onComplete(SVGAVideoEntity videoItem) {
|
||||
// SVGADrawable drawable = new SVGADrawable(videoItem, new SVGADynamicEntity());
|
||||
// svgaSurface.setImageDrawable(drawable);
|
||||
// svgaSurface.setCallback(new SVGACallback() {
|
||||
//
|
||||
// @Override
|
||||
// public void onStep(int i, double v) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onRepeat() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onPause() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onFinished() {
|
||||
// isPlaying = false;
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// svgaSurface.startAnimation();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onError() {
|
||||
// isPlaying = false;
|
||||
// }
|
||||
// });
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@@ -716,7 +472,6 @@ public class AvatarFrameView extends FrameLayout {
|
||||
}
|
||||
|
||||
// 隐藏所有视图
|
||||
// if (playerView != null) playerView.setVisibility(View.GONE);
|
||||
if (svgaSurface != null) svgaSurface.setVisibility(View.GONE);
|
||||
|
||||
|
||||
@@ -750,39 +505,7 @@ public class AvatarFrameView extends FrameLayout {
|
||||
*/
|
||||
private void releaseResources() {
|
||||
LogUtils.d(TAG, "Releasing all resources");
|
||||
|
||||
// if (isDestroyed) return;
|
||||
// 使用异步线程处理耗时操作
|
||||
new Thread(() -> {
|
||||
try {
|
||||
// 在后台线程处理文件操作和大对象清理
|
||||
// performHeavyCleanup();
|
||||
|
||||
// 回到主线程处理 UI 相关的清理
|
||||
mainHandler.post(() -> {
|
||||
performUICleanup();
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Logger.e(TAG, "Error in async releaseResources: " + e.getMessage());
|
||||
// 出错时仍在主线程清理 UI 资源
|
||||
mainHandler.post(() -> {
|
||||
performUICleanup();
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 在后台线程执行耗时的清理操作
|
||||
*/
|
||||
private void performHeavyCleanup() {
|
||||
try {
|
||||
// 清理缓存文件(如果需要)
|
||||
// 清理大对象引用等
|
||||
// clearCacheFiles();
|
||||
} catch (Exception e) {
|
||||
Logger.e(TAG, "Error in performHeavyCleanup: " + e.getMessage());
|
||||
}
|
||||
performUICleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -791,31 +514,16 @@ public class AvatarFrameView extends FrameLayout {
|
||||
private void performUICleanup() {
|
||||
try {
|
||||
// 停止并清理播放器
|
||||
if (mBinding != null && mBinding.playView != null) {
|
||||
if (mBinding != null) {
|
||||
try {
|
||||
mBinding.playView.stopPlay();
|
||||
} catch (Exception e) {
|
||||
Logger.e(TAG, "Error stopping playView: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 清理 ExoPlayer 资源
|
||||
// if (exoPlayer != null) {
|
||||
// try {
|
||||
// // 使用异步停止避免阻塞
|
||||
// exoPlayer.stop();
|
||||
// exoPlayer.clearVideoSurface();
|
||||
// } catch (Exception e) {
|
||||
// Logger.e(TAG, "Error releasing ExoPlayer resources: " + e.getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
// 清理 SVGA 资源
|
||||
if (svgaSurface != null) {
|
||||
try {
|
||||
// svgaSurface.pauseAnimation();
|
||||
// svgaSurface.clearAnimation();
|
||||
// svgaSurface.setImageDrawable(null);
|
||||
svgaSurface.stopAnimation(true);
|
||||
svgaSurface.clear();
|
||||
svgaSurface.clearAnimation();
|
||||
@@ -834,86 +542,23 @@ public class AvatarFrameView extends FrameLayout {
|
||||
*/
|
||||
public void release() {
|
||||
Logger.d("AvatarFrameView", "Public release called");
|
||||
// if (isDestroyed) return;
|
||||
// 确保在主线程中执行
|
||||
// if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
// mainHandler.post(this::release);
|
||||
// return;
|
||||
// }
|
||||
isDestroyed = true;
|
||||
|
||||
try {
|
||||
// 清空播放队列
|
||||
clearQueue();
|
||||
// 清理播放管理器
|
||||
if (playbackManager != null) {
|
||||
playbackManager.reset();
|
||||
}
|
||||
// 释放所有资源
|
||||
releaseResources();
|
||||
|
||||
|
||||
// 延迟清理其他资源
|
||||
mainHandler.postDelayed(() -> {
|
||||
// 清理 binding
|
||||
if (mBinding != null) {
|
||||
mBinding = null;
|
||||
}
|
||||
}, 100);
|
||||
|
||||
|
||||
// 清理 binding
|
||||
if (mBinding != null) {
|
||||
mBinding = null;
|
||||
}
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtils.e(TAG, "Error in AvatarFrameView release: " + e.getMessage());
|
||||
} finally {
|
||||
// 建议进行垃圾回收
|
||||
// MemoryOptimizationUtils.forceGC();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearQueue() {
|
||||
// if (isDestroyed) return;
|
||||
playQueue.clear();
|
||||
isPlaying = false;
|
||||
// 清理播放管理器中的任务
|
||||
if (playbackManager != null) {
|
||||
playbackManager.reset();
|
||||
}
|
||||
// 清理当前正在播放的内容
|
||||
clearPrevious();
|
||||
}
|
||||
|
||||
// 在类成员变量中添加
|
||||
private static final int PLAYBACK_TIMEOUT = 10000; // 10秒超时
|
||||
private Map<String, Long> playbackStartTimeMap = new HashMap<>();
|
||||
|
||||
// 添加超时检查方法
|
||||
private void startPlaybackTimeout(String url) {
|
||||
playbackStartTimeMap.put(url, System.currentTimeMillis());
|
||||
mainHandler.postDelayed(() -> checkPlaybackTimeout(url), PLAYBACK_TIMEOUT);
|
||||
}
|
||||
|
||||
private void checkPlaybackTimeout(String url) {
|
||||
Long startTime = playbackStartTimeMap.get(url);
|
||||
if (startTime != null && System.currentTimeMillis() - startTime > PLAYBACK_TIMEOUT) {
|
||||
LogUtils.w(TAG, "Playback timeout: " + url);
|
||||
playbackStartTimeMap.remove(url);
|
||||
|
||||
// 强制结束当前播放并继续下一个
|
||||
handlePlaybackComplete();
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelPlaybackTimeout(String url) {
|
||||
playbackStartTimeMap.remove(url);
|
||||
}
|
||||
|
||||
|
||||
private static class PlayItem {
|
||||
String url;
|
||||
int type;
|
||||
@@ -923,167 +568,4 @@ public class AvatarFrameView extends FrameLayout {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭特效
|
||||
*/
|
||||
public void closeEffect() {
|
||||
|
||||
// 清空队列
|
||||
clearQueue();
|
||||
// 释放资源
|
||||
// releaseResources();
|
||||
// 清空队列
|
||||
// playQueue.clear();
|
||||
// 关闭动画
|
||||
// if (mBinding.playView != null && isPlaying && mBinding.playView.isRunning()) {
|
||||
// mBinding.playView.setAnimation(null);
|
||||
// mBinding.playView.clearAnimation();
|
||||
// mBinding.playView.stopPlay();
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始循环播放SVGA动画
|
||||
*/
|
||||
public void startLoopingSvga(String assetName) {
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
mainHandler.post(() -> startLoopingSvga(assetName));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// clearPrevious(); // 清除之前的动画
|
||||
svgaSurface.setVisibility(View.VISIBLE);
|
||||
new SVGAParser(getContext()).decodeFromAssets(assetName, new SVGAParser.ParseCompletion() {
|
||||
@Override
|
||||
public void onComplete(SVGAVideoEntity svgaVideoEntity) {
|
||||
SVGADrawable drawable = new SVGADrawable(svgaVideoEntity);
|
||||
svgaSurface.setImageDrawable(drawable);
|
||||
svgaSurface.setLoops(0); // 0表示无限循环
|
||||
svgaSurface.startAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
Log.e(TAG, "解析SVGA文件失败: " + assetName);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "播放SVGA动画出错", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止并销毁当前SVGA动画
|
||||
*/
|
||||
public void stopSvga() {
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
mainHandler.post(() -> stopSvga());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (svgaSurface2 != null) {
|
||||
svgaSurface2.stopAnimation(true);
|
||||
svgaSurface2.setImageDrawable(null);
|
||||
svgaSurface2.setVisibility(View.GONE);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "停止SVGA动画出错", e);
|
||||
}
|
||||
}
|
||||
// 在 AvatarFrameView 类中添加以下代码
|
||||
|
||||
// 播放任务管理器
|
||||
// 替换现有的 PlaybackManager 类
|
||||
private static class PlaybackManager {
|
||||
private static final int MAX_CONCURRENT_PLAYBACKS = 3; // 增加并发数
|
||||
private int currentPlaybackCount = 0;
|
||||
private final Handler handler;
|
||||
|
||||
public PlaybackManager(Handler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public boolean canStartNewPlayback() {
|
||||
return currentPlaybackCount < MAX_CONCURRENT_PLAYBACKS;
|
||||
}
|
||||
|
||||
public void onStartPlayback() {
|
||||
currentPlaybackCount++;
|
||||
}
|
||||
|
||||
public void onFinishPlayback() {
|
||||
currentPlaybackCount = Math.max(0, currentPlaybackCount - 1);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
currentPlaybackCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 播放任务接口
|
||||
private interface PlaybackTask {
|
||||
void execute();
|
||||
}
|
||||
// 在 AvatarFrameView 类中添加以下代码
|
||||
|
||||
// private IAnimListener MP4PlaybackCallback;
|
||||
// 在 AvatarFrameView 类的成员变量区域添加单例实例
|
||||
|
||||
public void setAnimListener(IAnimListener mInstance) {
|
||||
mBinding.playView.setAnimListener(mInstance);
|
||||
}
|
||||
|
||||
// 添加统一的播放完成处理方法
|
||||
private void handlePlaybackComplete() {
|
||||
mainHandler.post(() -> {
|
||||
if (isDestroyed) return;
|
||||
|
||||
isPlaying = false;
|
||||
|
||||
// 通知播放管理器任务完成
|
||||
if (playbackManager != null) {
|
||||
playbackManager.reset();
|
||||
}
|
||||
|
||||
// 内存检查
|
||||
if (playQueue.size() % 5 == 0) {
|
||||
// performLightMemoryCleanup();
|
||||
}
|
||||
|
||||
// 播放下一个
|
||||
playNextFromQueue();
|
||||
});
|
||||
}
|
||||
|
||||
// 添加轻量级内存清理方法
|
||||
private void performLightMemoryCleanup() {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
|
||||
long maxMemory = runtime.maxMemory();
|
||||
double memoryUsage = (double) usedMemory / maxMemory;
|
||||
|
||||
// 内存使用超过70%时进行清理
|
||||
if (memoryUsage > 0.7) {
|
||||
// 清理SVGA缓存
|
||||
if (svgaCache.size() > 1) {
|
||||
// 保留最新的缓存项
|
||||
Iterator<Map.Entry<String, WeakReference<SVGAVideoEntity>>> iterator =
|
||||
svgaCache.entrySet().iterator();
|
||||
if (iterator.hasNext()) {
|
||||
iterator.next(); // 跳过最新的
|
||||
if (iterator.hasNext()) {
|
||||
iterator.remove(); // 移除较旧的
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 建议进行垃圾回收
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user