1123 lines
43 KiB
Java
1123 lines
43 KiB
Java
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);
|
||
|
||
}
|
||
|
||
|
||
}
|