Files
yusheng-android/MainModule/src/main/java/com/xscm/modulemain/dialog/TourClubDialogFragment.java

1123 lines
43 KiB
Java
Raw Normal View History

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);
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);
}
}