Files
yusheng-android/MainModule/src/main/java/com/xscm/modulemain/dialog/TourClubDialogFragment.java
2025-12-02 19:35:18 +08:00

1123 lines
43 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.xscm.modulemain.dialog;
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;
import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.LogUtils;
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;
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;
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());
}
public TourClubDialogFragment(){
}
public TourClubDialogFragment(String roomId){
this.roomId = roomId;
}
public static TourClubDialogFragment newInstance(String roomId) {
TourClubDialogFragment dialog = new TourClubDialogFragment(roomId);
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();
if (id == R.id.tv_jc) {
if (giftLists != null && !giftLists.isEmpty()) {
PrizePoolDialog prizePoolDialog = new PrizePoolDialog(ActivityUtils.getTopActivity());
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);
WebViewDialog dialog = new WebViewDialog(ActivityUtils.getTopActivity(), bundle);
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();
}
// 通过 ID 获取资源名称
String viewName = "";
try {
viewName = view.getContext().getResources().getResourceEntryName(id);
} catch (Exception e) {
viewName = "未知View ID: " + id;
}
LogUtils.e("tourClubDFragment","点击了" + viewName );
}
@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);
if (giftXlhChouAdapter != null) {
giftXlhChouAdapter.setNewData(giftLists);
}
// // 数据加载完成后启动自动滚动
// 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()));
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;
}
// 清理适配器引用 存在一次调用 giftXlhChouAdapter.setNewData(giftLists); 中giftXlhChouAdapter = null;
// if (giftXlhChouAdapter != null) {
// giftXlhChouAdapter = null;
// }
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();
// }
// 创建并显示对话框
xlhObtainDialog = new XlhObtainDialog(ActivityUtils.getTopActivity());
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);
}
}