2025-10-28 19:13:52 +08:00
|
|
|
|
package com.xscm.modulemain.dialog;
|
2025-10-24 17:55:15 +08:00
|
|
|
|
|
|
|
|
|
|
import android.app.Dialog;
|
|
|
|
|
|
import android.graphics.Typeface;
|
|
|
|
|
|
import android.os.Bundle;
|
|
|
|
|
|
import android.os.CountDownTimer;
|
|
|
|
|
|
import android.os.Handler;
|
|
|
|
|
|
import android.view.Gravity;
|
|
|
|
|
|
import android.view.View;
|
|
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
|
|
import android.view.Window;
|
|
|
|
|
|
|
|
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
|
|
|
|
import androidx.recyclerview.widget.LinearSnapHelper;
|
|
|
|
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
|
|
|
2025-11-27 11:47:10 +08:00
|
|
|
|
import com.blankj.utilcode.util.ActivityUtils;
|
2025-10-24 17:55:15 +08:00
|
|
|
|
import com.blankj.utilcode.util.GsonUtils;
|
2025-11-26 12:01:31 +08:00
|
|
|
|
import com.blankj.utilcode.util.LogUtils;
|
2025-10-24 17:55:15 +08:00
|
|
|
|
import com.xscm.moduleutil.R;
|
|
|
|
|
|
import com.xscm.moduleutil.base.BaseMvpDialogFragment;
|
|
|
|
|
|
import com.xscm.moduleutil.bean.GiftBean;
|
|
|
|
|
|
import com.xscm.moduleutil.bean.MqttXlhEnd;
|
|
|
|
|
|
import com.xscm.moduleutil.bean.RoomMessageEvent;
|
|
|
|
|
|
import com.xscm.moduleutil.bean.WalletBean;
|
|
|
|
|
|
import com.xscm.moduleutil.bean.XLHBean;
|
|
|
|
|
|
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.databinding.FragmentTourClubDialogBinding;
|
|
|
|
|
|
import com.xscm.moduleutil.dialog.RechargeDialogFragment;
|
2025-10-28 19:13:52 +08:00
|
|
|
|
import com.xscm.moduleutil.dialog.giftLottery.GiftLotteryContacts;
|
|
|
|
|
|
import com.xscm.moduleutil.dialog.giftLottery.GiftLotteryPresenter;
|
|
|
|
|
|
import com.xscm.moduleutil.dialog.giftLottery.GiftXlhChouAdapter;
|
|
|
|
|
|
import com.xscm.moduleutil.dialog.giftLottery.NewXlhRankingDialog;
|
|
|
|
|
|
import com.xscm.moduleutil.dialog.giftLottery.PrizePoolDialog;
|
|
|
|
|
|
import com.xscm.moduleutil.dialog.giftLottery.XlhObtainDialog;
|
|
|
|
|
|
import com.xscm.moduleutil.dialog.giftLottery.XlhRecordDialog;
|
2025-10-24 17:55:15 +08:00
|
|
|
|
import com.xscm.moduleutil.widget.CenterScrollHelper;
|
|
|
|
|
|
import com.xscm.moduleutil.widget.EqualSpaceItemDecoration;
|
|
|
|
|
|
|
|
|
|
|
|
import org.greenrobot.eventbus.Subscribe;
|
|
|
|
|
|
import org.greenrobot.eventbus.ThreadMode;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @author qx
|
|
|
|
|
|
* @data 2025/9/15
|
|
|
|
|
|
* @description: 玄镜之旅
|
|
|
|
|
|
*/
|
|
|
|
|
|
public class TourClubDialogFragment extends BaseMvpDialogFragment<GiftLotteryPresenter, FragmentTourClubDialogBinding> implements GiftLotteryContacts.View {
|
|
|
|
|
|
private String roomId;
|
|
|
|
|
|
private List<GiftBean> giftLists = new ArrayList<>();
|
|
|
|
|
|
private String getRule_url;
|
|
|
|
|
|
private CountDownTimer mCountDownTimer;
|
|
|
|
|
|
private long endTime; // 服务器返回的结束时间戳
|
|
|
|
|
|
private String num;
|
|
|
|
|
|
private NewXlhRankingDialog newXlhRankingDialog;
|
|
|
|
|
|
private XlhRecordDialog xlhRecordDialog;
|
|
|
|
|
|
private XlhObtainDialog xlhObtainDialog;
|
|
|
|
|
|
|
|
|
|
|
|
private GiftXlhChouAdapter giftXlhChouAdapter;
|
|
|
|
|
|
private CenterScrollHelper scrollHelper;
|
|
|
|
|
|
|
|
|
|
|
|
private static final int ITEM_COUNT = 24;
|
|
|
|
|
|
private static final int ROTATION_COUNT = 3;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Handler handler = new Handler();
|
|
|
|
|
|
private boolean isLotteryRunning = false;
|
|
|
|
|
|
private int scrollSpeed = 10; // 滚动速度
|
|
|
|
|
|
private int totalScrollTime = 5000; // 总滚动时间,单位:毫秒
|
|
|
|
|
|
private int targetPosition;
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isDrawing;//是否正在抽奖
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 添加自动滚动相关的成员变量
|
|
|
|
|
|
private Handler autoScrollHandler = new Handler();
|
|
|
|
|
|
private Runnable autoScrollRunnable;
|
|
|
|
|
|
private boolean isAutoScrolling = false;
|
|
|
|
|
|
private static final int AUTO_SCROLL_DELAY = 1000; // 1秒滚动一个item
|
|
|
|
|
|
private boolean vCheckbox=false;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected GiftLotteryPresenter bindPresenter() {
|
|
|
|
|
|
return new GiftLotteryPresenter(this, getActivity());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-27 11:47:10 +08:00
|
|
|
|
public TourClubDialogFragment(){
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public TourClubDialogFragment(String roomId){
|
|
|
|
|
|
this.roomId = roomId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-24 17:55:15 +08:00
|
|
|
|
public static TourClubDialogFragment newInstance(String roomId) {
|
2025-11-27 11:47:10 +08:00
|
|
|
|
TourClubDialogFragment dialog = new TourClubDialogFragment(roomId);
|
2025-10-24 17:55:15 +08:00
|
|
|
|
return dialog;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
|
|
|
|
|
Dialog dialog = super.onCreateDialog(savedInstanceState);
|
|
|
|
|
|
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
|
|
|
|
dialog.setCancelable(true);
|
|
|
|
|
|
return dialog;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected void initData() {
|
|
|
|
|
|
MvpPre.xlh(roomId);
|
|
|
|
|
|
MvpPre.wallet();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected void initDialogStyle(Window window) {
|
|
|
|
|
|
super.initDialogStyle(window);
|
|
|
|
|
|
window.setGravity(Gravity.BOTTOM);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onStart() {
|
|
|
|
|
|
super.onStart();
|
|
|
|
|
|
Window window = getDialog().getWindow();
|
|
|
|
|
|
if (window != null) {
|
|
|
|
|
|
// 获取屏幕高度
|
|
|
|
|
|
android.util.DisplayMetrics displayMetrics = new android.util.DisplayMetrics();
|
|
|
|
|
|
requireActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
|
|
|
|
|
int screenHeight = displayMetrics.heightPixels;
|
|
|
|
|
|
// 设置高度为屏幕高度的100%(全屏)
|
|
|
|
|
|
int heightInPx = (int) (screenHeight * 0.85);
|
|
|
|
|
|
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, heightInPx);
|
|
|
|
|
|
window.setBackgroundDrawableResource(android.R.color.transparent);
|
|
|
|
|
|
|
|
|
|
|
|
// 可选:设置动画样式(从底部弹出)
|
|
|
|
|
|
window.setWindowAnimations(R.style.CommonShowDialogBottom);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected void initView() {
|
|
|
|
|
|
mBinding.tvJc.setOnClickListener(this::onClick);
|
|
|
|
|
|
mBinding.llOne.setOnClickListener(this::onClick);
|
|
|
|
|
|
mBinding.llTen.setOnClickListener(this::onClick);
|
|
|
|
|
|
mBinding.llHundred.setOnClickListener(this::onClick);
|
|
|
|
|
|
mBinding.tvGz.setOnClickListener(this::onClick);
|
|
|
|
|
|
mBinding.tvBd.setOnClickListener(this::onClick);
|
|
|
|
|
|
mBinding.tvJl.setOnClickListener(this::onClick);
|
|
|
|
|
|
mBinding.exchangeLayout.setOnClickListener(this::onClick);
|
|
|
|
|
|
mBinding.vCheckbox.setOnClickListener(this::onClick);
|
|
|
|
|
|
giftXlhChouAdapter = new GiftXlhChouAdapter();
|
|
|
|
|
|
// 使用 LinearLayoutManager 横向滚动
|
|
|
|
|
|
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
|
|
|
|
|
|
mBinding.recycleView.setLayoutManager(layoutManager);
|
|
|
|
|
|
mBinding.recycleView.setOnFlingListener(null);
|
|
|
|
|
|
|
|
|
|
|
|
// 设置滚动辅助工具
|
|
|
|
|
|
LinearSnapHelper snapHelper = new LinearSnapHelper();
|
|
|
|
|
|
snapHelper.attachToRecyclerView(mBinding.recycleView);
|
|
|
|
|
|
|
|
|
|
|
|
// 添加 ItemDecoration 实现等宽分布
|
|
|
|
|
|
int spacing = getResources().getDimensionPixelSize(R.dimen.dp_15); // 根据需要调整间距
|
|
|
|
|
|
mBinding.recycleView.addItemDecoration(new EqualSpaceItemDecoration(3, spacing));
|
|
|
|
|
|
|
|
|
|
|
|
mBinding.recycleView.setAdapter(giftXlhChouAdapter);
|
|
|
|
|
|
// 初始化滚动帮助类
|
|
|
|
|
|
scrollHelper = new CenterScrollHelper(mBinding.recycleView);
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化时滚动到中间位置,确保有足够的前后数据
|
|
|
|
|
|
mBinding.recycleView.post(() -> {
|
|
|
|
|
|
if (giftXlhChouAdapter.getOriginalDataSize() > 0) {
|
|
|
|
|
|
int middlePosition = giftXlhChouAdapter.getItemCount() / 2;
|
|
|
|
|
|
mBinding.recycleView.scrollToPosition(middlePosition);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
mBinding.tvNumber.setText("x0");
|
|
|
|
|
|
mBinding.tvNumber.setTypeface(android.graphics.Typeface.create("semibold", Typeface.NORMAL));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加自动滚动相关的方法
|
|
|
|
|
|
private void startAutoScroll() {
|
|
|
|
|
|
// 如果已经在自动滚动或数据为空,则不启动
|
|
|
|
|
|
if (isAutoScrolling || giftLists == null || giftLists.isEmpty()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
isAutoScrolling = true;
|
|
|
|
|
|
autoScrollRunnable = new Runnable() {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void run() {
|
|
|
|
|
|
if (isAutoScrolling && mBinding != null && mBinding.recycleView != null) {
|
|
|
|
|
|
// 获取当前显示的第一个可见item位置
|
|
|
|
|
|
LinearLayoutManager layoutManager = (LinearLayoutManager) mBinding.recycleView.getLayoutManager();
|
|
|
|
|
|
if (layoutManager != null) {
|
|
|
|
|
|
int currentPosition = layoutManager.findFirstVisibleItemPosition();
|
|
|
|
|
|
|
|
|
|
|
|
// 如果没有完全可见的item,使用第一个可见item
|
|
|
|
|
|
if (currentPosition == RecyclerView.NO_POSITION) {
|
|
|
|
|
|
currentPosition = layoutManager.findFirstVisibleItemPosition();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果还是没有有效的position,从0开始
|
|
|
|
|
|
if (currentPosition == RecyclerView.NO_POSITION) {
|
|
|
|
|
|
currentPosition = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 计算下一个位置
|
|
|
|
|
|
int nextPosition = currentPosition + 1;
|
|
|
|
|
|
|
|
|
|
|
|
// 如果到达末尾,回到开始位置
|
|
|
|
|
|
if (nextPosition >= giftXlhChouAdapter.getItemCount()) {
|
|
|
|
|
|
nextPosition = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 平滑滚动到下一个位置
|
|
|
|
|
|
mBinding.recycleView.smoothScrollToPosition(nextPosition);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 1秒后继续滚动
|
|
|
|
|
|
autoScrollHandler.postDelayed(this, AUTO_SCROLL_DELAY);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 开始自动滚动
|
|
|
|
|
|
autoScrollHandler.postDelayed(autoScrollRunnable, AUTO_SCROLL_DELAY);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void stopAutoScroll() {
|
|
|
|
|
|
isAutoScrolling = false;
|
|
|
|
|
|
if (autoScrollRunnable != null) {
|
|
|
|
|
|
autoScrollHandler.removeCallbacks(autoScrollRunnable);
|
|
|
|
|
|
autoScrollRunnable = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 在抽奖结束后重新启动自动滚动
|
|
|
|
|
|
private void resumeAutoScrollAfterLottery() {
|
|
|
|
|
|
// 延迟一段时间后再启动自动滚动,让用户看到抽奖结果
|
|
|
|
|
|
mBinding.recycleView.postDelayed(() -> {
|
|
|
|
|
|
if (isVisible() && !isDrawing) {
|
|
|
|
|
|
startAutoScroll();
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 3000); // 3秒后重新开始自动滚动
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void onClick(View view) {
|
|
|
|
|
|
int id = view.getId();
|
2025-12-02 19:35:18 +08:00
|
|
|
|
|
2025-10-24 17:55:15 +08:00
|
|
|
|
if (id == R.id.tv_jc) {
|
|
|
|
|
|
if (giftLists != null && !giftLists.isEmpty()) {
|
2025-11-27 11:47:10 +08:00
|
|
|
|
PrizePoolDialog prizePoolDialog = new PrizePoolDialog(ActivityUtils.getTopActivity());
|
2025-10-24 17:55:15 +08:00
|
|
|
|
prizePoolDialog.updateData(giftLists, 13);
|
|
|
|
|
|
prizePoolDialog.show();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
com.hjq.toast.ToastUtils.show("奖池数据加载中,请稍后再试");
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (id == R.id.ll_one) {
|
|
|
|
|
|
if (!isDrawing) {
|
|
|
|
|
|
isDrawing = true;
|
|
|
|
|
|
prepareForNewLottery();
|
|
|
|
|
|
num = "1";
|
|
|
|
|
|
MvpPre.xlhChou(roomId, num);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// com.hjq.toast.ToastUtils.show("正在抽奖中...");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} else if (id == R.id.ll_ten) {
|
|
|
|
|
|
if (!isDrawing) {
|
|
|
|
|
|
isDrawing = true;
|
|
|
|
|
|
prepareForNewLottery();
|
|
|
|
|
|
num = "10";
|
|
|
|
|
|
MvpPre.xlhChou(roomId, num);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// com.hjq.toast.ToastUtils.show("正在抽奖中...");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} else if (id == R.id.ll_hundred) {
|
|
|
|
|
|
if (!isDrawing) {
|
|
|
|
|
|
isDrawing = true;
|
|
|
|
|
|
prepareForNewLottery();
|
|
|
|
|
|
num = "100";
|
|
|
|
|
|
MvpPre.xlhChou(roomId, num);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// com.hjq.toast.ToastUtils.show("正在抽奖中...");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} else if (id == R.id.tv_gz) {
|
|
|
|
|
|
Bundle bundle = new Bundle();
|
|
|
|
|
|
bundle.putString("url", getRule_url);
|
|
|
|
|
|
bundle.putInt("type", 13);
|
2025-11-27 11:47:10 +08:00
|
|
|
|
WebViewDialog dialog = new WebViewDialog(ActivityUtils.getTopActivity(), bundle);
|
2025-10-24 17:55:15 +08:00
|
|
|
|
dialog.show();
|
|
|
|
|
|
} else if (id == R.id.tv_bd) {
|
|
|
|
|
|
// 如果当前dialog存在且正在显示,先关闭
|
|
|
|
|
|
if (newXlhRankingDialog != null && newXlhRankingDialog.isVisible()) {
|
|
|
|
|
|
newXlhRankingDialog.dismiss();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
newXlhRankingDialog = NewXlhRankingDialog.newInstance(roomId);
|
|
|
|
|
|
newXlhRankingDialog.show(getChildFragmentManager(), "newXlhRankingDialog");
|
|
|
|
|
|
} else if (id == R.id.tv_jl) {
|
|
|
|
|
|
// 如果当前dialog存在且正在显示,先关闭
|
|
|
|
|
|
if (xlhRecordDialog != null && xlhRecordDialog.isVisible()) {
|
|
|
|
|
|
xlhRecordDialog.dismiss();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
xlhRecordDialog = XlhRecordDialog.newInstance(roomId);
|
|
|
|
|
|
xlhRecordDialog.show(getChildFragmentManager(), "XlhRecordDialog");
|
|
|
|
|
|
} else if (id == R.id.exchange_layout) {//钻石兑换
|
|
|
|
|
|
// ARouter.getInstance().build(ARouteConstants.CURRENCY).navigation();
|
|
|
|
|
|
RechargeDialogFragment.show(roomId, null, getActivity().getSupportFragmentManager(),"0","0");
|
|
|
|
|
|
}else if (id==R.id.v_checkbox){
|
|
|
|
|
|
mBinding.vCheckbox.setSelected(!mBinding.vCheckbox.isSelected());
|
|
|
|
|
|
vCheckbox=mBinding.vCheckbox.isSelected();
|
|
|
|
|
|
}
|
2025-12-02 19:35:18 +08:00
|
|
|
|
|
|
|
|
|
|
// 通过 ID 获取资源名称
|
|
|
|
|
|
String viewName = "";
|
|
|
|
|
|
try {
|
|
|
|
|
|
viewName = view.getContext().getResources().getResourceEntryName(id);
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
viewName = "未知View ID: " + id;
|
|
|
|
|
|
}
|
|
|
|
|
|
LogUtils.e("tourClubDFragment","点击了" + viewName );
|
2025-10-24 17:55:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected int getLayoutId() {
|
|
|
|
|
|
return R.layout.fragment_tour_club_dialog;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void getGiftListSuccess(BlindBoxBean blindBoxBean) {
|
|
|
|
|
|
if (blindBoxBean != null) {
|
|
|
|
|
|
|
|
|
|
|
|
getRule_url = blindBoxBean.getRule_url();
|
|
|
|
|
|
upTitle(blindBoxBean.getBox_price());
|
|
|
|
|
|
giftLists = blindBoxBean.getGift_list();
|
|
|
|
|
|
// 初始滚动到中间位置,避免边界问题
|
|
|
|
|
|
// mBinding.recycleView.scrollToPosition(Integer.MAX_VALUE / 2 - (Integer.MAX_VALUE / 2) % giftLists.size());
|
|
|
|
|
|
|
|
|
|
|
|
// 获取结束时间并启动倒计时
|
|
|
|
|
|
if (blindBoxBean.getXlh_end_time() != null && !blindBoxBean.getXlh_end_time().isEmpty()) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
endTime = Long.parseLong(blindBoxBean.getXlh_end_time());
|
|
|
|
|
|
mBinding.qxDjs.setEndTime(endTime);
|
|
|
|
|
|
// 假设 end_time 是时间戳字符串
|
|
|
|
|
|
// startCountdown();
|
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
|
// 如果不是时间戳,可能是日期字符串,需要相应解析
|
|
|
|
|
|
// 例如:2025-08-26 19:10:47
|
|
|
|
|
|
// 可以使用 SimpleDateFormat 解析
|
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (blindBoxBean.getGive_homeowner_gift() != null) {
|
|
|
|
|
|
// ImageUtils.loadHeadCC(blindBoxBean.getGive_homeowner_gift().getBase_image(), mBinding.giveIm);
|
|
|
|
|
|
mBinding.gvFzlw.setModel(blindBoxBean.getGive_homeowner_gift());
|
|
|
|
|
|
}
|
|
|
|
|
|
if (blindBoxBean.getLocking_gift() != null) {
|
|
|
|
|
|
// ImageUtils.loadHeadCC(blindBoxBean.getLocking_gift().getBase_image(), mBinding.giftImg);
|
|
|
|
|
|
// mBinding.tvGiftName.setText(blindBoxBean.getLocking_gift().getGift_name());
|
|
|
|
|
|
// mBinding.tvGiftPrice.setText(blindBoxBean.getLocking_gift().getGift_price());
|
|
|
|
|
|
// mBinding.tvGiftCount.setText(blindBoxBean.getLocking_gift().getGift_num());
|
|
|
|
|
|
mBinding.tvNumber.setText("x"+(blindBoxBean.getLocking_gift().getGift_num()!=null ?blindBoxBean.getLocking_gift().getGift_num():"0"));
|
|
|
|
|
|
mBinding.gvSdlw.setModel(blindBoxBean.getLocking_gift());
|
|
|
|
|
|
mBinding.gvSdlw.setIsLockGift(true);
|
|
|
|
|
|
mBinding.gvSdlw.stopAnimation();
|
|
|
|
|
|
mBinding.gvSdlw.startAnimation();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (blindBoxBean.getXlh_user() != null) {
|
|
|
|
|
|
// ImageUtils.loadHeadCC(blindBoxBean.getXlh_user().getAvatar(), mBinding.userPic);
|
|
|
|
|
|
// mBinding.userName.setText(blindBoxBean.getXlh_user().getNickname());
|
|
|
|
|
|
|
|
|
|
|
|
mBinding.gvXyz.setModel(blindBoxBean.getXlh_user());
|
|
|
|
|
|
}
|
|
|
|
|
|
mBinding.gvXyz.setIsLuckUser(true);
|
|
|
|
|
|
if (blindBoxBean.getHomeowner_user()!=null){
|
|
|
|
|
|
mBinding.gvFz.setModel(blindBoxBean.getHomeowner_user());
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
mBinding.gvFz.setIsLuckUser(false);
|
2025-11-26 12:01:31 +08:00
|
|
|
|
if (giftXlhChouAdapter != null) {
|
|
|
|
|
|
giftXlhChouAdapter.setNewData(giftLists);
|
|
|
|
|
|
}
|
2025-10-24 17:55:15 +08:00
|
|
|
|
// // 数据加载完成后启动自动滚动
|
|
|
|
|
|
// if (giftLists != null && !giftLists.isEmpty()) {
|
|
|
|
|
|
// mBinding.recycleView.post(() -> {
|
|
|
|
|
|
// // 确保在UI线程中启动自动滚动
|
|
|
|
|
|
// startAutoScroll();
|
|
|
|
|
|
// });
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
}else {
|
|
|
|
|
|
isDrawing = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int mboxPrice;
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: 2025/9/4 设置底部按钮文字
|
|
|
|
|
|
private void upTitle(int boxPrice) {
|
|
|
|
|
|
this.mboxPrice = boxPrice;
|
|
|
|
|
|
mBinding.tvOne.setText(boxPrice + "币一次");
|
|
|
|
|
|
mBinding.tvTen.setText((boxPrice * 10) + "币十次");
|
|
|
|
|
|
mBinding.tvHundred.setText((boxPrice * 100) + "币百次");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: 2025/8/29 接收im推送过来的消息
|
|
|
|
|
|
// @Subscribe(threadMode = ThreadMode.MAIN)
|
|
|
|
|
|
public void onMusicPlay(RoomMessageEvent message) {
|
|
|
|
|
|
if (message.getMsgType() == 1057) {
|
|
|
|
|
|
// UpView(message.getText().getXlh_data());
|
|
|
|
|
|
endTime = Long.parseLong(message.getText().getEnd_time() != null ? message.getText().getEnd_time() : "0");
|
|
|
|
|
|
// startCountdown();
|
|
|
|
|
|
// mBinding.tvGiftCount.setText(message.getText().getGift_num() != null ? message.getText().getGift_num() : "0");
|
|
|
|
|
|
// mBinding.userName.setText(message.getText().getFromUserInfo().getNickname() != null ? message.getText().getFromUserInfo().getNickname() : "");
|
|
|
|
|
|
// ImageUtils.loadHeadCC(message.getText().getFromUserInfo().getAvatar(), mBinding.userPic);
|
|
|
|
|
|
BlindBoxBean.xlhUser xlhUser = new BlindBoxBean.xlhUser();
|
|
|
|
|
|
xlhUser.setAvatar(message.getText().getFromUserInfo().getAvatar());
|
|
|
|
|
|
xlhUser.setNickname(message.getText().getFromUserInfo().getNickname());
|
|
|
|
|
|
mBinding.gvXyz.setModel(xlhUser);
|
|
|
|
|
|
mBinding.qxDjs.setEndTime(endTime);
|
2025-10-25 18:07:21 +08:00
|
|
|
|
mBinding.tvNumber.setText("x"+(message.getText().getGift_num()));
|
2025-10-24 17:55:15 +08:00
|
|
|
|
isDrawing=false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
|
|
|
|
|
public void onMessageReceived(RoomMessageEvent event) {
|
|
|
|
|
|
onMusicPlay( event);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
|
|
|
|
|
public void onMessageReceived(MqttXlhEnd event) {
|
|
|
|
|
|
XLHBean xlhBean = GsonUtils.fromJson(event.getMessage(), XLHBean.class);
|
|
|
|
|
|
if (xlhBean.getFrom_type()==103){
|
|
|
|
|
|
endTime = Long.parseLong(xlhBean.getEnd_time() != null ? xlhBean.getEnd_time() : "0");
|
|
|
|
|
|
BlindBoxBean.xlhUser xlhUser = new BlindBoxBean.xlhUser();
|
|
|
|
|
|
xlhUser.setAvatar(xlhBean.getFromUserInfo().getAvatar());
|
|
|
|
|
|
xlhUser.setNickname(xlhBean.getFromUserInfo().getNickname());
|
|
|
|
|
|
mBinding.gvXyz.setModel(xlhUser);
|
|
|
|
|
|
mBinding.qxDjs.setEndTime(endTime);
|
|
|
|
|
|
mBinding.tvNumber.setText("x"+(xlhBean.getGift_num() != null ? xlhBean.getGift_num() : "0"));
|
|
|
|
|
|
isDrawing=false;
|
|
|
|
|
|
if (xlhBean.getRoom_user()!=null){
|
|
|
|
|
|
mBinding.gvFz.setModel(xlhBean.getRoom_user());
|
|
|
|
|
|
}
|
|
|
|
|
|
mBinding.gvFz.setIsLuckUser(false);
|
|
|
|
|
|
}else if (xlhBean.getFrom_type()==104){
|
|
|
|
|
|
dismiss();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 启动倒计时
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void startCountdown() {
|
|
|
|
|
|
// 先释放之前的倒计时器
|
|
|
|
|
|
releaseCountDownTimer();
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前时间
|
|
|
|
|
|
long currentTime = System.currentTimeMillis() / 1000; // 转换为秒
|
|
|
|
|
|
long countdownTime = endTime - currentTime; // 计算剩余时间(秒)
|
|
|
|
|
|
|
|
|
|
|
|
// 如果倒计时时间已经结束,显示00:00
|
|
|
|
|
|
if (countdownTime <= 0) {
|
|
|
|
|
|
updateCountdownDisplay(0, 0);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 确保不超过最大时间59:59 (3599秒)
|
|
|
|
|
|
countdownTime = Math.min(countdownTime, 3599);
|
|
|
|
|
|
|
|
|
|
|
|
mCountDownTimer = new CountDownTimer(countdownTime * 1000, 1000) {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onTick(long millisUntilFinished) {
|
|
|
|
|
|
long seconds = millisUntilFinished / 1000;
|
|
|
|
|
|
long minutes = seconds / 60;
|
|
|
|
|
|
long remainingSeconds = seconds % 60;
|
|
|
|
|
|
updateCountdownDisplay((int) minutes, (int) remainingSeconds);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onFinish() {
|
|
|
|
|
|
updateCountdownDisplay(0, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
mCountDownTimer.start();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 更新倒计时显示
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param minutes 分钟数
|
|
|
|
|
|
* @param seconds 秒数
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void updateCountdownDisplay(int minutes, int seconds) {
|
|
|
|
|
|
// 假设布局中有以下TextView:
|
|
|
|
|
|
// mBinding.tvMinutes 十位分钟
|
|
|
|
|
|
// mBinding.tvMinutesUnit 个位分钟
|
|
|
|
|
|
// mBinding.tvSeconds 十位秒数
|
|
|
|
|
|
// mBinding.tvSecondsUnit 个位秒数
|
|
|
|
|
|
|
|
|
|
|
|
// 分解分钟数
|
|
|
|
|
|
int minutesTens = minutes / 10; // 十位分钟
|
|
|
|
|
|
int minutesUnits = minutes % 10; // 个位分钟
|
|
|
|
|
|
|
|
|
|
|
|
// 分解秒数
|
|
|
|
|
|
int secondsTens = seconds / 10; // 十位秒数
|
|
|
|
|
|
int secondsUnits = seconds % 10; // 个位秒数
|
|
|
|
|
|
|
|
|
|
|
|
// 更新UI显示(根据你的实际布局调整)
|
|
|
|
|
|
mBinding.tvTime1.setText(String.valueOf(minutesTens));
|
|
|
|
|
|
mBinding.tvTime2.setText(String.valueOf(minutesUnits));
|
|
|
|
|
|
mBinding.tvTime3.setText(String.valueOf(secondsTens));
|
|
|
|
|
|
mBinding.tvTime4.setText(String.valueOf(secondsUnits));
|
|
|
|
|
|
|
|
|
|
|
|
// 或者如果是一个整体的显示:
|
|
|
|
|
|
// mBinding.tvCountdown.setText(String.format("%02d:%02d", minutes, seconds));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 释放倒计时器资源
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void releaseCountDownTimer() {
|
|
|
|
|
|
if (mCountDownTimer != null) {
|
|
|
|
|
|
mCountDownTimer.cancel();
|
|
|
|
|
|
mCountDownTimer = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onDestroyView() {
|
|
|
|
|
|
super.onDestroyView();
|
|
|
|
|
|
releaseCountDownTimer();
|
|
|
|
|
|
// 清理所有待执行的任务
|
|
|
|
|
|
clearPendingTasks();
|
|
|
|
|
|
|
|
|
|
|
|
// 清理滚动帮助类
|
|
|
|
|
|
if (scrollHelper != null) {
|
|
|
|
|
|
scrollHelper = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-26 12:01:31 +08:00
|
|
|
|
// 清理适配器引用 存在一次调用 giftXlhChouAdapter.setNewData(giftLists); 中giftXlhChouAdapter = null;
|
|
|
|
|
|
// if (giftXlhChouAdapter != null) {
|
|
|
|
|
|
// giftXlhChouAdapter = null;
|
|
|
|
|
|
// }
|
2025-10-24 17:55:15 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (xlhRecordDialog != null && xlhRecordDialog.isVisible()) {
|
|
|
|
|
|
xlhRecordDialog.dismiss();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果当前dialog存在且正在显示,先关闭
|
|
|
|
|
|
if (newXlhRankingDialog != null && newXlhRankingDialog.isVisible()) {
|
|
|
|
|
|
newXlhRankingDialog.dismiss();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (xlhObtainDialog != null && xlhObtainDialog.isShowing()) {
|
|
|
|
|
|
xlhObtainDialog.dismiss();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
stopAutoScroll();
|
|
|
|
|
|
autoScrollHandler.removeCallbacksAndMessages(null);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void drawGiftListSuccess(BlindReslutBean blindReslutBean) {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void getMyRecordSuccess(List<GiftBean> data) {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void getAllRecordSuccess(List<GiftBean> data) {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void finishRefreshLoadMore() {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private int icon;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void wallet(WalletBean walletBean) {
|
|
|
|
|
|
if (walletBean != null) {
|
|
|
|
|
|
icon = (int) Double.parseDouble(
|
|
|
|
|
|
(walletBean.getCoin() != null && !walletBean.getCoin().isEmpty())
|
|
|
|
|
|
? walletBean.getCoin()
|
|
|
|
|
|
: "0"
|
|
|
|
|
|
);
|
|
|
|
|
|
mBinding.tvIcon.setText(walletBean.getCoin()!=null && !walletBean.getCoin().isEmpty() ?walletBean.getCoin():"0");
|
|
|
|
|
|
showView();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void showView() {
|
|
|
|
|
|
if (icon>=mboxPrice){
|
|
|
|
|
|
mBinding.llOne.setClickable( true);
|
|
|
|
|
|
}else {
|
|
|
|
|
|
mBinding.llOne.setClickable( false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (icon>=mboxPrice*10){
|
|
|
|
|
|
mBinding.llTen.setClickable( true);
|
|
|
|
|
|
}else {
|
|
|
|
|
|
mBinding.llTen.setClickable( false);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (icon>=mboxPrice*100){
|
|
|
|
|
|
mBinding.llHundred.setClickable( true);
|
|
|
|
|
|
}else {
|
|
|
|
|
|
mBinding.llHundred.setClickable( false);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Runnable pendingLotteryRunnable;
|
|
|
|
|
|
private Runnable pendingCenteringRunnable;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void xlhChouSuccess(List<XlhDrawBean> data) {
|
|
|
|
|
|
if (data != null) {
|
|
|
|
|
|
if (vCheckbox){
|
|
|
|
|
|
showResultDialog(data);
|
|
|
|
|
|
}else {
|
|
|
|
|
|
// showResultDialog(data);
|
|
|
|
|
|
|
|
|
|
|
|
// 取消之前可能存在的任务
|
|
|
|
|
|
clearPendingTasks();
|
|
|
|
|
|
// 抽奖完成后执行动画滚动
|
|
|
|
|
|
pendingLotteryRunnable = new Runnable() {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void run() {
|
|
|
|
|
|
// 清理之前的状态
|
|
|
|
|
|
if (giftXlhChouAdapter != null) {
|
|
|
|
|
|
giftXlhChouAdapter.clearSelection();
|
|
|
|
|
|
}
|
|
|
|
|
|
int winningPosition = findHighestValueWinningPosition(data);//这是获取到的中奖位置下标
|
|
|
|
|
|
if (winningPosition != -1) {
|
|
|
|
|
|
if (scrollHelper == null) {
|
|
|
|
|
|
scrollHelper = new CenterScrollHelper(mBinding.recycleView);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 计算在循环列表中的目标位置(滚动几圈后停在目标位置)
|
|
|
|
|
|
int loopCount = 4; // 滚动4圈
|
|
|
|
|
|
int originalSize = giftLists.size();///这是列表的总大小
|
|
|
|
|
|
// 计算目标在循环列表中的位置(确保在中间区域)
|
|
|
|
|
|
///这是计算总圈数的大小
|
|
|
|
|
|
int middleBaseIndex = (loopCount * originalSize);
|
|
|
|
|
|
///这里是展示在中奖的位置,加上总圈数的大小,
|
|
|
|
|
|
int targetLoopIndex = middleBaseIndex + (winningPosition % originalSize);
|
|
|
|
|
|
|
|
|
|
|
|
// 使用scrollWithCircles方法执行带动画的滚动(带完成回调)
|
|
|
|
|
|
scrollHelper.scrollWithCircles(
|
|
|
|
|
|
targetLoopIndex, // 在循环列表中的位置
|
|
|
|
|
|
loopCount, // 滚动圈数
|
|
|
|
|
|
1000, // 每个item滚动时间200ms(控制速度)
|
|
|
|
|
|
originalSize, // 原始数据大小
|
|
|
|
|
|
() -> { // 滚动完成回调
|
|
|
|
|
|
// 滚动完成后更新选中状态(使用原始位置)
|
|
|
|
|
|
if (giftXlhChouAdapter != null) {
|
|
|
|
|
|
giftXlhChouAdapter.setSelectedPosition(winningPosition);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 滚动完成后延迟一小段时间再居中,确保UI更新完成
|
|
|
|
|
|
pendingCenteringRunnable = new Runnable() {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void run() {
|
|
|
|
|
|
// 手动将选中项居中
|
|
|
|
|
|
centerSelectedItem(winningPosition, originalSize);
|
|
|
|
|
|
|
|
|
|
|
|
// 显示结果对话框
|
|
|
|
|
|
getActivity().runOnUiThread(() -> {
|
|
|
|
|
|
scrollHelper = null;
|
|
|
|
|
|
showResultDialog(data);
|
|
|
|
|
|
// 抽奖结束后重新启动自动滚动
|
|
|
|
|
|
// resumeAutoScrollAfterLottery();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
mBinding.recycleView.postDelayed(pendingCenteringRunnable, 1000);
|
|
|
|
|
|
}
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果没有找到中奖位置,直接显示对话框
|
|
|
|
|
|
showResultDialog(data);
|
|
|
|
|
|
// 抽奖结束后重新启动自动滚动
|
|
|
|
|
|
// resumeAutoScrollAfterLottery();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
mBinding.recycleView.postDelayed(pendingLotteryRunnable, 1000);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}else {
|
|
|
|
|
|
isDrawing=false;
|
|
|
|
|
|
// 抽奖失败也重新启动自动滚动
|
|
|
|
|
|
// resumeAutoScrollAfterLottery();
|
|
|
|
|
|
}
|
|
|
|
|
|
MvpPre.wallet();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 为新的抽奖做准备,清理之前的状态
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void prepareForNewLottery() {
|
|
|
|
|
|
|
|
|
|
|
|
// 停止自动滚动
|
|
|
|
|
|
stopAutoScroll();
|
|
|
|
|
|
|
|
|
|
|
|
// 取消之前可能存在的任务
|
|
|
|
|
|
clearPendingTasks();
|
|
|
|
|
|
|
|
|
|
|
|
// 清除之前的选择状态
|
|
|
|
|
|
if (giftXlhChouAdapter != null) {
|
|
|
|
|
|
giftXlhChouAdapter.clearSelection();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 重置滚动帮助类
|
|
|
|
|
|
if (scrollHelper != null) {
|
|
|
|
|
|
scrollHelper.reset();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 停止可能正在进行的滚动
|
|
|
|
|
|
mBinding.recycleView.stopScroll();
|
|
|
|
|
|
|
|
|
|
|
|
// 清理可能存在的回调
|
|
|
|
|
|
if (mBinding.recycleView.getHandler() != null) {
|
|
|
|
|
|
mBinding.recycleView.getHandler().removeCallbacksAndMessages(null);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 重新初始化滚动帮助类
|
|
|
|
|
|
scrollHelper = new CenterScrollHelper(mBinding.recycleView);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 清除所有待执行的任务
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void clearPendingTasks() {
|
|
|
|
|
|
// 取消抽奖动画任务
|
|
|
|
|
|
if (pendingLotteryRunnable != null) {
|
|
|
|
|
|
mBinding.recycleView.removeCallbacks(pendingLotteryRunnable);
|
|
|
|
|
|
pendingLotteryRunnable = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 取消居中任务
|
|
|
|
|
|
if (pendingCenteringRunnable != null) {
|
|
|
|
|
|
mBinding.recycleView.removeCallbacks(pendingCenteringRunnable);
|
|
|
|
|
|
pendingCenteringRunnable = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 停止可能正在进行的滚动
|
|
|
|
|
|
mBinding.recycleView.stopScroll();
|
|
|
|
|
|
|
|
|
|
|
|
// 清理handler中的所有消息
|
|
|
|
|
|
if (mBinding.recycleView.getHandler() != null) {
|
|
|
|
|
|
mBinding.recycleView.getHandler().removeCallbacksAndMessages(null);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void startLotteryAnimation(int targetIndex) {
|
|
|
|
|
|
// 确保适配器有数据
|
|
|
|
|
|
if (giftXlhChouAdapter == null || giftXlhChouAdapter.getOriginalDataSize() <= 0) {
|
|
|
|
|
|
showResultDialogWithoutAnimation(targetIndex);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LinearLayoutManager layoutManager = (LinearLayoutManager) mBinding.recycleView.getLayoutManager();
|
|
|
|
|
|
if (layoutManager == null) {
|
|
|
|
|
|
showResultDialogWithoutAnimation(targetIndex);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前第一个可见的item位置
|
|
|
|
|
|
int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();
|
|
|
|
|
|
if (firstVisiblePosition == RecyclerView.NO_POSITION) {
|
|
|
|
|
|
firstVisiblePosition = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前在原始数据中的实际位置
|
|
|
|
|
|
int currentActualPosition = firstVisiblePosition % giftXlhChouAdapter.getOriginalDataSize();
|
|
|
|
|
|
|
|
|
|
|
|
// 计算需要滚动的总item数
|
|
|
|
|
|
// 滚动指定圈数 + 从当前位置到目标位置的距离
|
|
|
|
|
|
int itemsToScroll = ROTATION_COUNT * giftXlhChouAdapter.getOriginalDataSize()
|
|
|
|
|
|
+ (targetIndex - currentActualPosition + giftXlhChouAdapter.getOriginalDataSize())
|
|
|
|
|
|
% giftXlhChouAdapter.getOriginalDataSize();
|
|
|
|
|
|
|
|
|
|
|
|
// 计算目标位置
|
|
|
|
|
|
int targetPosition = firstVisiblePosition + itemsToScroll;
|
|
|
|
|
|
|
|
|
|
|
|
// 确保目标位置在合理范围内
|
|
|
|
|
|
int maxPosition = giftXlhChouAdapter.getItemCount() - 1;
|
|
|
|
|
|
if (targetPosition > maxPosition) {
|
|
|
|
|
|
targetPosition = maxPosition;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 确保目标位置有效
|
|
|
|
|
|
if (targetPosition >= 0) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
SmoothScroller smoothScroller = new SmoothScroller(getActivity(), targetPosition);
|
|
|
|
|
|
layoutManager.startSmoothScroll(smoothScroller);
|
|
|
|
|
|
} catch (IllegalArgumentException e) {
|
|
|
|
|
|
// 如果仍然出现异常,使用备选方案
|
|
|
|
|
|
showResultDialogWithoutAnimation(targetIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showResultDialogWithoutAnimation(targetIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void showResultDialogWithoutAnimation(int targetIndex) {
|
|
|
|
|
|
// 直接设置选中状态
|
|
|
|
|
|
if (giftXlhChouAdapter != null) {
|
|
|
|
|
|
giftXlhChouAdapter.setSelectedPosition(targetIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 延迟显示结果对话框
|
|
|
|
|
|
mBinding.recycleView.postDelayed(() -> {
|
|
|
|
|
|
// 创建假的XlhDrawBean数据用于显示结果
|
|
|
|
|
|
List<XlhDrawBean> fakeData = new ArrayList<>();
|
|
|
|
|
|
// 这里根据需要构造假数据
|
|
|
|
|
|
showResultDialog(fakeData);
|
|
|
|
|
|
}, 300);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private class SmoothScroller extends androidx.recyclerview.widget.LinearSmoothScroller {
|
|
|
|
|
|
|
|
|
|
|
|
private int targetPosition;
|
|
|
|
|
|
|
|
|
|
|
|
public SmoothScroller(android.content.Context context, int targetPosition) {
|
|
|
|
|
|
super(context);
|
|
|
|
|
|
this.targetPosition = targetPosition;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected int calculateTimeForScrolling(int dx) {
|
|
|
|
|
|
// 自定义滚动时间,实现速度变化
|
|
|
|
|
|
float distance = Math.abs(dx);
|
|
|
|
|
|
float speed = 1f;
|
|
|
|
|
|
if (distance < 100) {
|
|
|
|
|
|
speed = 0.3f; // 慢
|
|
|
|
|
|
} else if (distance < 300) {
|
|
|
|
|
|
speed = 1f; // 快
|
|
|
|
|
|
} else {
|
|
|
|
|
|
speed = 0.3f; // 慢
|
|
|
|
|
|
}
|
|
|
|
|
|
return (int) (distance / speed);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
|
|
|
|
|
|
// 将目标项移动到屏幕中心
|
|
|
|
|
|
return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public int getTargetPosition() {
|
|
|
|
|
|
// 添加更严格的边界检查
|
|
|
|
|
|
if (giftXlhChouAdapter != null && targetPosition >= 0 && targetPosition < giftXlhChouAdapter.getItemCount()) {
|
|
|
|
|
|
return targetPosition;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 如果超出范围,返回一个安全的位置
|
|
|
|
|
|
if (giftXlhChouAdapter != null && giftXlhChouAdapter.getItemCount() > 0) {
|
|
|
|
|
|
return Math.max(0, Math.min(targetPosition, giftXlhChouAdapter.getItemCount() - 1));
|
|
|
|
|
|
}
|
|
|
|
|
|
return 0; // 返回默认位置
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 将指定的原始位置item居中显示
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param originalPosition 原始数据中的位置
|
|
|
|
|
|
* @param originalSize 原始数据大小
|
|
|
|
|
|
*/
|
|
|
|
|
|
// 新增优化的居中方法
|
|
|
|
|
|
private void centerSelectedItem(int originalPosition, int originalSize) {
|
|
|
|
|
|
LinearLayoutManager layoutManager = (LinearLayoutManager) mBinding.recycleView.getLayoutManager();
|
|
|
|
|
|
if (layoutManager == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 计算出需要滚动到的目标位置(确保在中间可见区域)
|
|
|
|
|
|
int targetPosition = originalPosition + 4 * originalSize;
|
|
|
|
|
|
|
|
|
|
|
|
// 先滚动到目标位置附近
|
|
|
|
|
|
mBinding.recycleView.scrollToPosition(targetPosition);
|
|
|
|
|
|
|
|
|
|
|
|
// 使用post确保布局完成后进行精确居中
|
|
|
|
|
|
mBinding.recycleView.post(() -> {
|
|
|
|
|
|
View targetView = layoutManager.findViewByPosition(targetPosition);
|
|
|
|
|
|
if (targetView == null) {
|
|
|
|
|
|
// 如果目标view不可见,使用smoothScrollToPosition
|
|
|
|
|
|
mBinding.recycleView.smoothScrollToPosition(targetPosition);
|
|
|
|
|
|
// 再次尝试居中
|
|
|
|
|
|
mBinding.recycleView.postDelayed(() -> {
|
|
|
|
|
|
View refreshedView = layoutManager.findViewByPosition(targetPosition);
|
|
|
|
|
|
if (refreshedView != null) {
|
|
|
|
|
|
performCentering(layoutManager, refreshedView);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 50);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
performCentering(layoutManager, targetView);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 执行实际的居中操作
|
|
|
|
|
|
private void performCentering(LinearLayoutManager layoutManager, View targetView) {
|
|
|
|
|
|
// 计算RecyclerView的中心点
|
|
|
|
|
|
int recyclerViewWidth = mBinding.recycleView.getWidth();
|
|
|
|
|
|
int recyclerViewCenter = recyclerViewWidth / 2;
|
|
|
|
|
|
|
|
|
|
|
|
// 计算目标view的中心点
|
|
|
|
|
|
int targetViewLeft = targetView.getLeft();
|
|
|
|
|
|
int targetViewWidth = targetView.getWidth();
|
|
|
|
|
|
int targetViewCenter = targetViewLeft + targetViewWidth / 2;
|
|
|
|
|
|
|
|
|
|
|
|
// 计算需要滚动的偏移量
|
|
|
|
|
|
int offset = targetViewCenter - recyclerViewCenter;
|
|
|
|
|
|
|
|
|
|
|
|
// 精确滚动使目标view居中
|
|
|
|
|
|
mBinding.recycleView.scrollBy(offset, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 直接滚动到指定位置并居中
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param targetPosition 目标位置
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void directScrollToCenter(int targetPosition) {
|
|
|
|
|
|
if (mBinding.recycleView.getLayoutManager() == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
mBinding.recycleView.post(() -> {
|
|
|
|
|
|
int screenWidth = mBinding.recycleView.getWidth();
|
|
|
|
|
|
if (screenWidth <= 0) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 计算item宽度
|
|
|
|
|
|
int itemWidth = screenWidth / 3;
|
|
|
|
|
|
|
|
|
|
|
|
// 计算目标位置的左边缘
|
|
|
|
|
|
int targetLeft = targetPosition * itemWidth;
|
|
|
|
|
|
|
|
|
|
|
|
// 计算使item居中需要滚动到的位置
|
|
|
|
|
|
int targetScrollX = targetLeft - (screenWidth - itemWidth) / 2;
|
|
|
|
|
|
|
|
|
|
|
|
// 直接滚动到目标位置
|
|
|
|
|
|
mBinding.recycleView.scrollBy(
|
|
|
|
|
|
targetScrollX - mBinding.recycleView.computeHorizontalScrollOffset(),
|
|
|
|
|
|
0
|
|
|
|
|
|
);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 滚动到指定位置并使该位置的item居中显示
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param selectedPosition 选中的原始位置
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void scrollToCenterWithSelected(int selectedPosition) {
|
|
|
|
|
|
if (mBinding.recycleView.getLayoutManager() == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
int screenWidth = mBinding.recycleView.getWidth();
|
|
|
|
|
|
if (screenWidth <= 0) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 计算item宽度
|
|
|
|
|
|
int itemWidth = screenWidth / 3;
|
|
|
|
|
|
|
|
|
|
|
|
// 计算要滚动到的中心位置(使selectedPosition的item居中)
|
|
|
|
|
|
int middlePositionInLoop = (giftXlhChouAdapter.getItemCount() / 2 / giftXlhChouAdapter.getOriginalDataSize())
|
|
|
|
|
|
* giftXlhChouAdapter.getOriginalDataSize() + selectedPosition;
|
|
|
|
|
|
|
|
|
|
|
|
// 滚动到目标位置
|
|
|
|
|
|
mBinding.recycleView.smoothScrollToPosition(middlePositionInLoop);
|
|
|
|
|
|
|
|
|
|
|
|
// 额外确保居中
|
|
|
|
|
|
mBinding.recycleView.postDelayed(() -> {
|
|
|
|
|
|
if (scrollHelper != null) {
|
|
|
|
|
|
scrollHelper.scrollToCenter(middlePositionInLoop);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 300);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 显示抽奖结果对话框
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param data 中奖数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void showResultDialog(List<XlhDrawBean> data) {
|
|
|
|
|
|
isDrawing = false;
|
|
|
|
|
|
// 创建并显示对话框
|
|
|
|
|
|
// 关闭之前可能存在的对话框
|
|
|
|
|
|
// if (xlhObtainDialog != null && xlhObtainDialog.isShowing()) {
|
|
|
|
|
|
// xlhObtainDialog.dismiss();
|
|
|
|
|
|
// }
|
|
|
|
|
|
// 创建并显示对话框
|
2025-11-27 11:47:10 +08:00
|
|
|
|
xlhObtainDialog = new XlhObtainDialog(ActivityUtils.getTopActivity());
|
2025-10-24 17:55:15 +08:00
|
|
|
|
xlhObtainDialog.setOnGiftItemClickListener(new XlhObtainDialog.OnGiftItemClickListener() {
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onPlayAgainClick() {
|
|
|
|
|
|
isDrawing = true;
|
|
|
|
|
|
// 处理再玩一次点击事件
|
|
|
|
|
|
MvpPre.xlhChou(roomId, num);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onCloseClick() {
|
|
|
|
|
|
// 处理关闭点击事件
|
|
|
|
|
|
if (xlhObtainDialog != null && xlhObtainDialog.isShowing()) {
|
|
|
|
|
|
isDrawing = false;
|
|
|
|
|
|
xlhObtainDialog.dismiss();
|
|
|
|
|
|
}
|
|
|
|
|
|
xlhObtainDialog = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
xlhObtainDialog.show();
|
|
|
|
|
|
xlhObtainDialog.setGiftList(data);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据中奖结果找到最高价值奖品在giftLists中的位置
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param data 中奖结果列表
|
|
|
|
|
|
* @return 最高价值奖品在giftLists中的下标,如果没有找到则返回-1
|
|
|
|
|
|
*/
|
|
|
|
|
|
private int findHighestValueWinningPosition(List<XlhDrawBean> data) {
|
|
|
|
|
|
if (data == null || data.isEmpty() || giftLists == null || giftLists.isEmpty()) {
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int targetPosition = -1;
|
|
|
|
|
|
int highestPrice = -1;
|
|
|
|
|
|
|
|
|
|
|
|
// 遍历giftLists查找中奖项目
|
|
|
|
|
|
for (int i = 0; i < giftLists.size(); i++) {
|
|
|
|
|
|
GiftBean giftBean = giftLists.get(i);
|
|
|
|
|
|
|
|
|
|
|
|
// 在中奖数据中查找匹配的礼品
|
|
|
|
|
|
for (XlhDrawBean xlhDrawBean : data) {
|
|
|
|
|
|
// 比较gift_id是否匹配
|
|
|
|
|
|
if (giftBean.getGift_id().equals(String.valueOf(xlhDrawBean.getGift_id()))) {
|
|
|
|
|
|
// 解析价格,处理可能的NumberFormatException
|
|
|
|
|
|
try {
|
|
|
|
|
|
int currentPrice = Integer.parseInt(giftBean.getGift_price());
|
|
|
|
|
|
// 如果当前价格更高,则更新目标位置和最高价格
|
|
|
|
|
|
if (currentPrice > highestPrice) {
|
|
|
|
|
|
highestPrice = currentPrice;
|
|
|
|
|
|
targetPosition = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
|
// 如果价格解析失败,使用默认值0进行比较
|
|
|
|
|
|
if (highestPrice <= 0) {
|
|
|
|
|
|
highestPrice = 0;
|
|
|
|
|
|
targetPosition = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
break; // 找到匹配项后跳出内层循环
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return targetPosition;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 精确将指定位置的item滚动到中心
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param position 目标位置
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void preciseScrollToCenter(int position) {
|
|
|
|
|
|
if (mBinding.recycleView.getLayoutManager() == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
int screenWidth = mBinding.recycleView.getWidth();
|
|
|
|
|
|
if (screenWidth <= 0) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 计算item宽度
|
|
|
|
|
|
int itemWidth = screenWidth / 3;
|
|
|
|
|
|
|
|
|
|
|
|
// 计算屏幕中心位置
|
|
|
|
|
|
int screenCenter = screenWidth / 2;
|
|
|
|
|
|
|
|
|
|
|
|
// 计算目标item的中心位置(在当前可见区域中)
|
|
|
|
|
|
int targetItemCenter = (mBinding.recycleView.computeHorizontalScrollOffset() / itemWidth) * itemWidth
|
|
|
|
|
|
+ position * itemWidth + itemWidth / 2;
|
|
|
|
|
|
|
|
|
|
|
|
// 计算需要滚动的距离使目标item居中
|
|
|
|
|
|
int scrollDistance = targetItemCenter - screenCenter;
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前滚动位置
|
|
|
|
|
|
int currentScrollX = mBinding.recycleView.computeHorizontalScrollOffset();
|
|
|
|
|
|
|
|
|
|
|
|
// 执行滚动使选中项居中
|
|
|
|
|
|
mBinding.recycleView.smoothScrollBy(scrollDistance - currentScrollX, 0);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|