package com.weishitech.jtwzjiaotongcx.fragment.lilv;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import android.app.AlertDialog;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.widget.Toast;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.viewpager2.widget.ViewPager2;
import com.hfd.common.net.GenericsCallback;
import com.hfd.common.net.HttpBuiler;
import com.hfd.common.net.JsonGenericsSerializator;
import com.hfd.common.net.JsonUtil;
import com.hfd.common.net.Url;
import com.hfd.common.util.ToastUtil;
import com.weishitech.jtwzjiaotongcx.R;
import com.weishitech.jtwzjiaotongcx.adtakubase.activity.BaseBindActivity;
import com.weishitech.jtwzjiaotongcx.bean.DrivingQueryReqDto;
import com.weishitech.jtwzjiaotongcx.bean.Question;
import com.weishitech.jtwzjiaotongcx.bean.QuestionSource;
import com.weishitech.jtwzjiaotongcx.databinding.ActivityTestBinding;
import com.weishitech.jtwzjiaotongcx.dialog.DialogUtils;
import com.weishitech.jtwzjiaotongcx.fragment.Adapter.QuestionAdapter;
import com.weishitech.jtwzjiaotongcx.fragment.Adapter.QuestionNumberAdapter;
import com.weishitech.jtwzjiaotongcx.fragment.Adapter.SpaceItemDecoration;
import com.weishitech.jtwzjiaotongcx.utils.LogUtil;
import com.weishitech.jtwzjiaotongcx.utils.OnMultiClickListener;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import okhttp3.Call;
public class TestActivity extends BaseBindActivity<ActivityTestBinding> {
private List<Question.DataBean> list;
int subject = 1;
private int type;
private QuestionNumberAdapter adapter;
private QuestionAdapter adapter1;
private static final int PAGE_SIZE = 10;
private int currentPageIndex = 1; // 当前显示第几页
private boolean isShowingDialog = false;
private int correct, wrong;
private Date examTime;
private Date submitTime;
private CountDownTimer countDownTimer;
private long timeLeftInMillis = 45 * 60 * 1000; // 45分钟
private boolean timerRunning = false;
// 添加这个字段:记录每道题是否已作答
private boolean[] answeredArray; // 初始化为 new boolean[list.size()]
private int currentPageStart = 0; // 添加这个字段
private Runnable autoNextRunnable; // 可取消的延迟任务
private Handler mainHandler = new Handler(Looper.getMainLooper());
@Override
protected void init() {
type = getIntent().getIntExtra("type", 0);
if (type == 1){
subject = 1;
}else{
subject = 4;
}
mBinding.cbExamSelect.setChecked(true);
// 根据类型设置不同的UI模式
if (type == 11 || type == 12 || type == 13) {
mBinding.rlExamNormal.setVisibility(GONE);
mBinding.tvExamSubmit.setVisibility(VISIBLE);
mBinding.llExamSimulation.setVisibility(VISIBLE);
startTimer();
examTime = new Date();
} else {
mBinding.rlExamNormal.setVisibility(VISIBLE);
mBinding.tvExamSubmit.setVisibility(GONE);
mBinding.llExamSimulation.setVisibility(GONE);
}
mBinding.ivBack.setOnClickListener(new OnMultiClickListener() {
@Override
public void onMultiClick(View v) {
showExitConfirmDialog();
}
});
//提交试卷
mBinding.tvExamSubmit.setOnClickListener(new OnMultiClickListener() {
@Override
public void onMultiClick(View v) {
submitExam();
}
});
mBinding.tvExamStart.setOnClickListener(new OnMultiClickListener() {
@Override
public void onMultiClick(View v) {
switchToStartMode();
}
});
mBinding.tvExamAnswer.setOnClickListener(new OnMultiClickListener() {
@Override
public void onMultiClick(View v) {
switchToAnswerMode();
}
});
// 初始化 RecyclerView
mBinding.rvQuestionNumbers.setLayoutManager(
new GridLayoutManager(this, 5) // 每行 10 个
);
// 添加间距:垂直 8dp,水平 4dp
int verticalSpacing = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());
int horizontalSpacing = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());
mBinding.rvQuestionNumbers.addItemDecoration(
new SpaceItemDecoration(verticalSpacing, horizontalSpacing)
);
setupViewPager();
requestQuestions();
}
private void setupViewPager() {
list = new ArrayList<>();
adapter1 = new QuestionAdapter(list, type, new QuestionAdapter.OnAnswerSelectedListener() {
@Override
public void onAnswerSelected(int position, String answer) {
// 可以在这里处理答案选择事件
LogUtil.info("题目 " + position + " 选择了答案: " + answer);
}
@Override
public void onAnswerConfirmed(int position, boolean isCorrect) {
// === 标记该题为已答 ===
if (position >= 0 && position < answeredArray.length) {
answeredArray[position] = true;
}
if (isCorrect) {
correct++;
mBinding.tvExamCorrect.setText(String.valueOf(correct));
if (mBinding.cbExamSelect.isChecked() && position < list.size() - 1) {
// 自动下一题
mBinding.viewPager.setCurrentItem(mBinding.viewPager.getCurrentItem() + 1);
}
} else {
wrong++;
mBinding.tvExamWrong.setText(String.valueOf(wrong));
}
// 更新进度显示
updateProgress();
// === 通知 Adapter 更新题号列表 UI ===
if (adapter != null) {
int posInPage = position - currentPageStart;
if (posInPage >= 0 && posInPage < adapter.getItemCount()) {
adapter.notifyItemChanged(posInPage); // 触发 onBindViewHolder
}
}
// === 自动跳转逻辑开始 ===
boolean shouldAutoNext = mBinding.cbExamSelect.isChecked() && position < list.size() - 1;
Log.d("AutoNext", "shouldAutoNext = " + shouldAutoNext +
", isChecked=" + mBinding.cbExamSelect.isChecked() +
", pos=" + position + ", size=" + list.size());
if (shouldAutoNext) {
// 创建一个可复用的任务
final Runnable nextTask = () -> {
int current = mBinding.viewPager.getCurrentItem();
if (current == position) { // 确保仍在此页
Log.d("AutoNext", "执行自动跳转到 " + (position + 1));
mBinding.viewPager.setCurrentItem(position + 1, true);
} else {
Log.d("AutoNext", "跳转取消:用户已手动翻页");
}
};
// 清除之前的任务(防重复)
if (autoNextRunnable != null) {
mainHandler.removeCallbacks(autoNextRunnable);
}
autoNextRunnable = nextTask;
// 提交延迟任务
mainHandler.postDelayed(autoNextRunnable, 6000);
Log.d("AutoNext", "已设置 6 秒后自动跳转");
}
}
});
mBinding.viewPager.setAdapter(adapter1);
mBinding.viewPager.setOffscreenPageLimit(3); // 预加载3个页面
// 添加页面切换监听
mBinding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
// === 用户手动翻页时,取消自动跳转任务 ===
if (autoNextRunnable != null) {
mainHandler.removeCallbacks(autoNextRunnable);
}
// 更新顶部计数器
updateQuestionCount();
// 计算目标页码(每20题一页)
int targetPageIndex = (position / PAGE_SIZE) + 1;
if (targetPageIndex != currentPageIndex) {
// 如果当前页不包含该题,则切换到对应页
currentPageIndex = targetPageIndex;
loadCurrentPage(); // 重新加载题号列表(如 21-40)
}
// 延迟一点再设置高亮,等 RecyclerView 数据刷新完成
mBinding.rvQuestionNumbers.post(() -> {
if (adapter != null) {
adapter.setCurrentQuestion(position);
}
});
}
});
}
/**
* 更新题目计数显示
*/
private void updateQuestionCount() {
if (list != null && !list.isEmpty()) {
String current = String.valueOf(mBinding.viewPager.getCurrentItem() + 1);
String total = "/" + list.size();
mBinding.tvExamCurrNum.setText(current);
mBinding.tvExamNum.setText(total);
}
}
/**
* 更新答题进度
*/
private void updateProgress() {
int answered = correct + wrong;
int total = list.size();
LogUtil.info("答题进度: " + answered + "/" + total + ", 正确: " + correct + ", 错误: " + wrong);
}
private void setupQuestionNumberAdapter() {
adapter = new QuestionNumberAdapter(list.size(),answeredArray, globalPosition -> {
Toast.makeText(this, "跳转到第 " + (globalPosition + 1) + " 题", Toast.LENGTH_SHORT).show();
// === 计算并更新当前页码 ===
int targetPageIndex = (globalPosition / PAGE_SIZE) + 1;
if (targetPageIndex != currentPageIndex) {
currentPageIndex = targetPageIndex;
loadCurrentPage(); // 加载新的题号页
}
// 跳转页面
mBinding.viewPager.setCurrentItem(globalPosition, false); // 不平滑
// 这里你可以通过 ViewPager 或 Fragment 切换题目
// vpExam.setCurrentItem(globalPosition);
adapter.setCurrentQuestion(globalPosition);
// 判断是否是本页最后一个题
boolean isLastInCurrentPage = (globalPosition + 1) % PAGE_SIZE == 0 || globalPosition == list.size() - 1;
if (isLastInCurrentPage) {
maybeShowNextPageDialog(); // 智能判断是否弹框
}
});
mBinding.rvQuestionNumbers.setAdapter(adapter);
// 加载第一页
loadCurrentPage();
}
// 检查是否需要加载下一批
private void loadCurrentPage() {
if (adapter != null) {
currentPageStart = (currentPageIndex - 1) * PAGE_SIZE; // 更新起始位置
adapter.loadPage(currentPageIndex, PAGE_SIZE);
adapter.notifyDataSetChanged();
}
}
/**
* 如果还有下一页,则弹出“是否进入下一组”对话框
* 否则直接提示“已完成所有题目”
*/
private void maybeShowNextPageDialog() {
int nextPageStartIndex = currentPageIndex * PAGE_SIZE; // 下一页第一个题的 globalPosition(0-based)
if (nextPageStartIndex >= list.size()) {
// 已经是最后一页了(比如当前是第5页,81-100),无需弹框
Toast.makeText(this, "恭喜完成全部题目!", Toast.LENGTH_SHORT).show();
return;
}
// 还有下一页,才弹框询问
new AlertDialog.Builder(this)
.setTitle("进入下一组")
.setMessage("已完成本组题目,是否加载下一组?")
.setPositiveButton("确定", (dialog, which) -> {
currentPageIndex++;
loadCurrentPage(); // 加载下一页题号
})
.setNegativeButton("取消", null)
.show();
}
/**
* 请求题目数据
*/
private void requestQuestions() {
showDialog();
HttpBuiler.postString(Url.getDrivingQuery)
.content(JsonUtil.toJson(new DrivingQueryReqDto("c1", String.valueOf(subject), "rand")))
.build()
.execute(new GenericsCallback<QuestionSource>(new JsonGenericsSerializator()) {
@Override
public void onError(Call call, Exception e, int id) {
dissmiss();
LogUtil.info("=网络请求错误=============" + e.getMessage());
ToastUtil.showShortToast("网络请求失败: " + e.getMessage());
// 加载本地缓存或默认数据
loadDefaultQuestions();
}
@Override
public void onResponse(QuestionSource response, int id) {
dissmiss();
if (response.getCode() == Url.SuccessCode_0) {
if (response.getData() != null && !response.getData().isEmpty()) {
// 转换数据格式
list = convertQuestionData(response.getData());
adapter1.updateQuestions(list);
updateQuestionCount();
// === 初始化答题状态数组 ===
answeredArray = new boolean[list.size()];
java.util.Arrays.fill(answeredArray, false); // 初始都没答
setupQuestionNumberAdapter(); // <<< 添加这一行
// ToastUtil.showShortToast("加载成功,共" + list.size() + "道题目");
} else {
ToastUtil.showShortToast("未查询到题目数据");
loadDefaultQuestions();
}
} else {
LogUtil.info("服务器返回错误: " + response.getMessage());
ToastUtil.showShortToast(response.getMsg());
loadDefaultQuestions();
}
}
});
}
/**
* 将QuestionSource转换为Question.DataBean
*/
private List<Question.DataBean> convertQuestionData(List<QuestionSource.DataBean> sourceList) {
List<Question.DataBean> resultList = new ArrayList<>();
for (QuestionSource.DataBean source : sourceList) {
Question.DataBean target = new Question.DataBean();
// 设置基本属性
target.setTitle(source.getQuestion());
target.setOp1(source.getItem1());
target.setOp2(source.getItem2());
target.setOp3(source.getItem3());
target.setOp4(source.getItem4());
target.setAnalysis(source.getExplains());
target.setTitlePic(source.getUrl());
// 映射答案格式
String mappedAnswer = mapAnswer(source.getAnswer());
target.setAnswer(mappedAnswer);
// 判断题目类型:1-判断题,2-多选题
if ("1".equals(source.getAnswer()) || "2".equals(source.getAnswer())) {
target.setTitleType(1); // 判断题
} else {
target.setTitleType(2); // 多选题
}
resultList.add(target);
}
return resultList;
}
/**
* 映射答案格式
*/
private String mapAnswer(String answer) {
switch (answer) {
case "1": return "A";
case "2": return "B";
case "3": return "C";
case "4": return "D";
case "7": return "AB";
case "8": return "AC";
case "9": return "AD";
case "10": return "BC";
case "11": return "BD";
case "12": return "CD";
case "13": return "ABC";
case "14": return "ABD";
case "15": return "ACD";
case "16": return "BCD";
case "17": return "ABCD";
default: return answer;
}
}
/**
* 加载默认题目数据(网络失败时使用)
*/
private void loadDefaultQuestions() {
list = new ArrayList<>();
// 添加一些默认题目
Question.DataBean defaultQuestion = new Question.DataBean();
defaultQuestion.setTitle("这是默认题目,请检查网络连接");
defaultQuestion.setOp1("选项A");
defaultQuestion.setOp2("选项B");
defaultQuestion.setOp3("");
defaultQuestion.setOp4("");
defaultQuestion.setAnswer("A");
defaultQuestion.setTitleType(1);
defaultQuestion.setAnalysis("这是默认题目的解析");
list.add(defaultQuestion);
adapter1.updateQuestions(list);
updateQuestionCount();
// 初始化答题状态
answeredArray = new boolean[list.size()];
}
/**
* 切换到开始答题模式
*/
private void switchToStartMode() {
mBinding.tvExamStart.setTextColor(ContextCompat.getColor(mContext, R.color.white));
mBinding.tvExamStart.setSelected(true);
mBinding.tvExamAnswer.setTextColor(ContextCompat.getColor(mContext, R.color.tab_select_u));
mBinding.tvExamAnswer.setSelected(false);
adapter1.setAnswerMode(false);
}
/**
* 切换到答案模式
*/
private void switchToAnswerMode() {
mBinding.tvExamAnswer.setTextColor(ContextCompat.getColor(mContext, R.color.white));
mBinding.tvExamAnswer.setSelected(true);
mBinding.tvExamStart.setTextColor(ContextCompat.getColor(mContext, R.color.tab_select_u));
mBinding.tvExamStart.setSelected(false);
adapter1.setAnswerMode(true);
}
/**
* 提交考试 confirmSubmit();
*/
/**
* 提交考试
*/
private void submitExam() {
final int total = list.size();
final int answered = correct + wrong;
int firstUnansweredIndex = -1;
// 找出第一个未答的题目索引
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getShowAnswer().isEmpty()) {
firstUnansweredIndex = i;
break;
}
}
if (firstUnansweredIndex != -1) {
final int index = firstUnansweredIndex; // 明确标记为 effectively final
// 有未答的题目
String message = "还有 " + (total - answered) + " 道题目未完成!\n是否跳转到第 " + (index + 1) + " 题?";
DialogUtils.showConfirmDialog(this, "提示", message,
() -> jumpToUnansweredQuestion(index), // 确认:跳转
() -> confirmSubmit() // 取消:继续提交
);
} else {
// 全部已答,直接提交
confirmSubmit();
}
}
private void confirmSubmit() {
int total = list.size();
int answered = correct + wrong;
int unAnswered = total - answered;
int score = correct;
double accuracy = (double) correct / total * 100;
boolean isPass = score >= 90; // 驾考一般 90 分合格
String result = isPass ? " 恭喜通过!" : " 未通过,请继续努力";
String message = String.format(
"%s\n\n" +
"【最终成绩】\n" +
"总题数:%d\n" +
"已答:%d(未答:%d)\n" +
"答对:%d|答错:%d\n\n" +
"得分:%d / %d\n" +
"正确率:%.1f%%",
result, total, answered, unAnswered, correct, wrong, score, total, accuracy
);
DialogUtils.showConfirmDialog(this, "考试结果", message, () -> {
submitTime = new Date();
// saveExamRecord(score, total);
finish();
});
}
/**
* 跳转到指定未答题
*/
private void jumpToUnansweredQuestion(int position) {
// 设置当前题目为未答题
mBinding.viewPager.setCurrentItem(position);
// 同步更新题号高亮
adapter.setCurrentQuestion(position);
// 可选:让题号栏滚动到可视区域
scrollToQuestionNumber(position);
}
/**
* 滚动到指定题号(使其可见)
*/
private void scrollToQuestionNumber(int globalPosition) {
int targetPage = (globalPosition / PAGE_SIZE) + 1;
if (targetPage != currentPageIndex) {
// 如果不在当前页,先加载对应页
currentPageIndex = targetPage;
loadCurrentPage();
}
// 延迟一点再设置高亮和滚动
mBinding.rvQuestionNumbers.post(() -> {
adapter.setCurrentQuestion(globalPosition);
// 计算在当前页中的偏移
int posInPage = globalPosition % PAGE_SIZE;
if (posInPage < adapter.getItemCount()) {
mBinding.rvQuestionNumbers.scrollToPosition(posInPage);
}
});
}
/**
* 显示退出确认对话框
*/
private void showExitConfirmDialog() {
DialogUtils.showConfirmDialog(this, "提示", "确定要退出考试吗?退出后进度将不会保存。",
() -> { // 确认退出
if (countDownTimer != null) {
countDownTimer.cancel();
}
finish();
}
);
}
/**
* 保存考试记录
*/
private void saveExamRecord() {
// 这里实现考试记录的保存逻辑
// 可以保存到本地数据库或上传到服务器
LogUtil.info("考试记录保存: 正确" + correct + "题,错误" + wrong + "题,用时" + getExamDuration() + "分钟");
}
/**
* 获取考试用时(分钟)
*/
private long getExamDuration() {
if (examTime != null && submitTime != null) {
return (submitTime.getTime() - examTime.getTime()) / (1000 * 60);
}
return 0;
}
/**
* 开始计时器
*/
private void startTimer() {
if (!timerRunning) {
countDownTimer = new CountDownTimer(timeLeftInMillis, 1000) {
@Override
public void onTick(long millisUntilFinished) {
timeLeftInMillis = millisUntilFinished;
updateCountdownText();
}
@Override
public void onFinish() {
timerRunning = false;
mBinding.tvExamTime.setText("00:00");
// 时间到自动交卷
autoSubmitExam();
}
}.start();
timerRunning = true;
}
}
/**
* 自动交卷(时间到)
*/
private void autoSubmitExam() {
DialogUtils.showConfirmDialog(this, "时间到", "考试时间已结束,系统将自动交卷。", new DialogUtils.OnConfirmListener() {
@Override
public void onConfirm() {
submitTime = new Date();
saveExamRecord();
finish();
}
});
}
/**
* 更新倒计时显示
*/
private void updateCountdownText() {
int minutes = (int) (timeLeftInMillis / 1000) / 60;
int seconds = (int) (timeLeftInMillis / 1000) % 60;
String timeFormatted = String.format("%02d:%02d", minutes, seconds);
mBinding.tvExamTime.setText(timeFormatted);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (countDownTimer != null) {
countDownTimer.cancel();
}
}
}package com.weishitech.jtwzjiaotongcx.fragment.Adapter;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import android.graphics.Color;
import android.os.Build;
import android.text.Html;
import android.text.SpannableString;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.hfd.common.util.ImageLoaderManager;
import com.hfd.common.util.ToastUtil;
import com.weishitech.jtwzjiaotongcx.R;
import com.weishitech.jtwzjiaotongcx.bean.Question;
import com.weishitech.jtwzjiaotongcx.utils.TextSpanUtils;
import java.util.List;
public class QuestionAdapter extends RecyclerView.Adapter<QuestionAdapter.QuestionViewHolder> {
private int type;
private List<Question.DataBean> questions;
private static boolean isAnswerMode;
private OnAnswerSelectedListener listener;
public QuestionAdapter(List<Question.DataBean> questions, int type, OnAnswerSelectedListener listener) {
this.questions = questions;
this.type = type;
this.listener = listener;
isAnswerMode = false;
}
public void setAnswerMode(boolean answerMode) {
isAnswerMode = answerMode;
notifyDataSetChanged();
}
@NonNull
@Override
public QuestionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_question, parent, false);
return new QuestionViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull QuestionViewHolder holder, int position) {
Question.DataBean data = questions.get(position);
holder.bind(data, type, isAnswerMode, listener, position);
}
@Override
public int getItemCount() {
return questions.size();
}
public void updateQuestions(List<Question.DataBean> newQuestions) {
this.questions.clear();
this.questions.addAll(newQuestions);
notifyDataSetChanged();
}
public interface OnAnswerSelectedListener {
void onAnswerSelected(int position, String answer);
void onAnswerConfirmed(int position, boolean isCorrect);
}
static class QuestionViewHolder extends RecyclerView.ViewHolder {
private TextView tvQuestionTopic;
private LinearLayout optionA, optionB, optionC, optionD, llQuestionAnswer;
private TextView tvOptionALabel, tvOptionBLabel, tvOptionCLabel, tvOptionDLabel;
private TextView tvOptionAContent, tvOptionBContent, tvOptionCContent, tvOptionDContent;
private ImageView ivOptionAResult, ivOptionBResult, ivOptionCResult, ivOptionDResult;
private Button btnQuestionSubmit;
private TextView tvQuestionAnswer, tvQuestionChoice;
private TextView tvQuestionParse, tvQuestionParseContent;
private ImageView ivCoverQuestion;
public QuestionViewHolder(@NonNull View itemView) {
super(itemView);
initViews(itemView);
}
private void initViews(View itemView) {
tvQuestionTopic = itemView.findViewById(R.id.tv_question_topic);
optionA = itemView.findViewById(R.id.ll_question_a);
optionB = itemView.findViewById(R.id.ll_question_b);
optionC = itemView.findViewById(R.id.ll_question_c);
optionD = itemView.findViewById(R.id.ll_question_d);
tvOptionALabel = itemView.findViewById(R.id.tv_item_question_a);
tvOptionBLabel = itemView.findViewById(R.id.tv_item_question_b);
tvOptionCLabel = itemView.findViewById(R.id.tv_item_question_c);
tvOptionDLabel = itemView.findViewById(R.id.tv_item_question_d);
tvOptionAContent = itemView.findViewById(R.id.tv_question_content_a);
tvOptionBContent = itemView.findViewById(R.id.tv_question_content_b);
tvOptionCContent = itemView.findViewById(R.id.tv_question_content_c);
tvOptionDContent = itemView.findViewById(R.id.tv_question_content_d);
ivOptionAResult = itemView.findViewById(R.id.iv_item_question_a);
ivOptionBResult = itemView.findViewById(R.id.iv_item_question_b);
ivOptionCResult = itemView.findViewById(R.id.iv_item_question_c);
ivOptionDResult = itemView.findViewById(R.id.iv_item_question_d);
btnQuestionSubmit = itemView.findViewById(R.id.btn_question_submit);
llQuestionAnswer = itemView.findViewById(R.id.ll_question_answer);
tvQuestionAnswer = itemView.findViewById(R.id.tv_question_answer);
tvQuestionChoice = itemView.findViewById(R.id.tv_question_choice);
tvQuestionParse = itemView.findViewById(R.id.tv_question_parse);
tvQuestionParseContent = itemView.findViewById(R.id.tv_question_parse_content);
ivCoverQuestion = itemView.findViewById(R.id.iv_cover_question);
}
public void bind(Question.DataBean data, int type, boolean isAnswerMode, OnAnswerSelectedListener listener, int position) {
// 设置题目标题
setQuestionTitle(data);
// 设置选项可见性
setOptionsVisibility(data);
// 重置选项选择状态
resetSelectionStates(data);
// 处理图片显示
handleImageDisplay(data);
// 设置模式相关显示
setupModeDisplay(data, type, isAnswerMode);
// 绑定选项点击事件
bindOptions(data, listener, isAnswerMode);
// 设置提交按钮
setupSubmitButton(data, listener, position, type);
}
private void setQuestionTitle(Question.DataBean data) {
String title;
String highlightText;
if (data.getTitleType() == 1) {
title = "判断 " + data.getTitle();
highlightText = "判断";
} else {
title = "多选 " + data.getTitle();
highlightText = "多选";
}
SpannableString spannableString = TextSpanUtils.setBlueRoundedText(tvQuestionTopic, title, highlightText);
tvQuestionTopic.setText(spannableString);
}
private void setOptionsVisibility(Question.DataBean data) {
optionA.setVisibility(data.getOp1().isEmpty() ? GONE : VISIBLE);
optionB.setVisibility(data.getOp2().isEmpty() ? GONE : VISIBLE);
optionC.setVisibility(data.getOp3().isEmpty() ? GONE : VISIBLE);
optionD.setVisibility(data.getOp4().isEmpty() ? GONE : VISIBLE);
}
private void resetSelectionStates(Question.DataBean data) {
data.setSelectA(false);
data.setSelectB(false);
data.setSelectC(false);
data.setSelectD(false);
}
private void handleImageDisplay(Question.DataBean data) {
if (data!= null && !TextUtils.isEmpty(data.getTitlePic())) {
ivCoverQuestion.setVisibility(VISIBLE);
ImageLoaderManager.loadImage(itemView.getContext(),data.getTitlePic(),ivCoverQuestion);
} else {
ivCoverQuestion.setVisibility(GONE);
}
}
private void setupModeDisplay(Question.DataBean data, int type, boolean isAnswerMode) {
if (isAnswerMode) {
// 答案模式:显示正确答案和解析
showAnswerMode(data, type);
} else {
// 答题模式
if (!data.getShowAnswer().isEmpty()) {
showUserAnswerResult(data, type);
} else {
showNormalMode();
}
}
}
private void bindOptions(Question.DataBean data, OnAnswerSelectedListener listener, boolean isAnswerMode) {
bindOption(optionA, tvOptionALabel, tvOptionAContent, ivOptionAResult,
"A", data.getOp1(), data, listener, isAnswerMode);
bindOption(optionB, tvOptionBLabel, tvOptionBContent, ivOptionBResult,
"B", data.getOp2(), data, listener, isAnswerMode);
bindOption(optionC, tvOptionCLabel, tvOptionCContent, ivOptionCResult,
"C", data.getOp3(), data, listener, isAnswerMode);
bindOption(optionD, tvOptionDLabel, tvOptionDContent, ivOptionDResult,
"D", data.getOp4(), data, listener, isAnswerMode);
}
private void bindOption(LinearLayout optionLayout, TextView labelView, TextView contentView,
ImageView resultView, String label, String content,
Question.DataBean data, OnAnswerSelectedListener listener, boolean isAnswerMode) {
contentView.setText(content);
setOptionSelected(data, label);
if (!isAnswerMode && data.getShowAnswer().isEmpty()) {
optionLayout.setOnClickListener(v -> handleOptionClick(data, label, listener));
} else {
optionLayout.setOnClickListener(null);
optionLayout.setClickable(false);
}
}
private void handleOptionClick(Question.DataBean data, String label, OnAnswerSelectedListener listener) {
boolean isJudgmentQuestion = data.getTitleType() == 1;
if (isJudgmentQuestion) {
// 判断题:单选逻辑
handleJudgmentQuestionClick(data, label);
} else {
// 多选题:多选逻辑
handleMultipleQuestionClick(data, label);
}
// 更新UI
setOptionSelected(data, label);
// 回调当前选择的答案
String currentAnswer = getCurrentAnswer(data);
listener.onAnswerSelected(getAdapterPosition(), currentAnswer);
}
private void handleJudgmentQuestionClick(Question.DataBean data, String label) {
// 重置所有选项
data.setSelectA(false);
data.setSelectB(false);
data.setSelectC(false);
data.setSelectD(false);
// 设置当前选中选项
switch (label) {
case "A":
data.setSelectA(true);
break;
case "B":
data.setSelectB(true);
break;
case "C":
data.setSelectC(true);
break;
case "D":
data.setSelectD(true);
break;
}
}
private void handleMultipleQuestionClick(Question.DataBean data, String label) {
// 多选题:切换当前选项的选中状态
switch (label) {
case "A":
data.setSelectA(!data.isSelectA());
break;
case "B":
data.setSelectB(!data.isSelectB());
break;
case "C":
data.setSelectC(!data.isSelectC());
break;
case "D":
data.setSelectD(!data.isSelectD());
break;
}
}
private String getCurrentAnswer(Question.DataBean data) {
StringBuilder answer = new StringBuilder();
if (data.isSelectA()) answer.append("A");
if (data.isSelectB()) answer.append("B");
if (data.isSelectC()) answer.append("C");
if (data.isSelectD()) answer.append("D");
return answer.toString();
}
private void setupSubmitButton(Question.DataBean data, OnAnswerSelectedListener listener, int position, int type) {
btnQuestionSubmit.setOnClickListener(v -> {
String userAnswer = getCurrentAnswer(data);
if (!userAnswer.isEmpty()) {
data.setShowAnswer(userAnswer);
showUserAnswerResult(data, type);
boolean isCorrect = userAnswer.equals(data.getAnswer());
listener.onAnswerConfirmed(position, isCorrect);
} else {
ToastUtil.showShortToastCenter("请至少选择一个答案");
}
});
}
private void showAnswerMode(Question.DataBean data, int type) {
// 隐藏结果图标,显示标签
setResultIconsVisibility(GONE);
setOptionLabelsVisibility(VISIBLE);
// 显示正确答案和解析
showCorrectAnswer(data, type);
}
private void showUserAnswerResult(Question.DataBean data, int type) {
// 显示用户答案的结果
showOptionResults(data);
tvQuestionChoice.setText(data.getShowAnswer());
showAnswerLayout(data, type);
btnQuestionSubmit.setVisibility(GONE);
}
private void showNormalMode() {
setResultIconsVisibility(GONE);
setOptionLabelsVisibility(VISIBLE);
hideAnswerLayout();
btnQuestionSubmit.setVisibility(VISIBLE);
}
private void showOptionResults(Question.DataBean data) {
showOptionResult("A", data, ivOptionAResult, tvOptionALabel);
showOptionResult("B", data, ivOptionBResult, tvOptionBLabel);
showOptionResult("C", data, ivOptionCResult, tvOptionCLabel);
showOptionResult("D", data, ivOptionDResult, tvOptionDLabel);
}
private void showOptionResult(String option, Question.DataBean data, ImageView resultView, TextView labelView) {
if (data.getShowAnswer().contains(option)) {
labelView.setVisibility(GONE);
resultView.setVisibility(VISIBLE);
if (data.getAnswer().contains(option)) {
resultView.setImageResource(R.mipmap.im_exam_correct);
} else {
resultView.setImageResource(R.mipmap.im_exam_wrong);
}
}
}
private void showCorrectAnswer(Question.DataBean data, int type) {
llQuestionAnswer.setVisibility(VISIBLE);
btnQuestionSubmit.setVisibility(GONE);
tvQuestionAnswer.setText(data.getAnswer());
// 设置正确答案的选中状态用于显示
setCorrectAnswerSelected(data);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
tvQuestionParseContent.setText(Html.fromHtml(data.getAnalysis(), Html.FROM_HTML_MODE_LEGACY));
} else {
tvQuestionParseContent.setText(Html.fromHtml(data.getAnalysis()));
}
boolean shouldHideParse = type == 11 || type == 12;
tvQuestionParse.setVisibility(shouldHideParse ? GONE : VISIBLE);
tvQuestionParseContent.setVisibility(shouldHideParse ? GONE : VISIBLE);
}
private void setCorrectAnswerSelected(Question.DataBean data) {
data.setSelectA(data.getAnswer().contains("A"));
data.setSelectB(data.getAnswer().contains("B"));
data.setSelectC(data.getAnswer().contains("C"));
data.setSelectD(data.getAnswer().contains("D"));
}
private void showAnswerLayout(Question.DataBean data, int type) {
llQuestionAnswer.setVisibility(VISIBLE);
tvQuestionAnswer.setText(data.getAnswer());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
tvQuestionParseContent.setText(Html.fromHtml(data.getAnalysis(), Html.FROM_HTML_MODE_LEGACY));
} else {
tvQuestionParseContent.setText(Html.fromHtml(data.getAnalysis()));
}
boolean shouldHideParse = type == 11 || type == 12;
tvQuestionParse.setVisibility(shouldHideParse ? GONE : VISIBLE);
tvQuestionParseContent.setVisibility(shouldHideParse ? GONE : VISIBLE);
}
private void hideAnswerLayout() {
llQuestionAnswer.setVisibility(GONE);
tvQuestionParse.setVisibility(GONE);
tvQuestionParseContent.setVisibility(GONE);
}
private void setResultIconsVisibility(int visibility) {
ivOptionAResult.setVisibility(visibility);
ivOptionBResult.setVisibility(visibility);
ivOptionCResult.setVisibility(visibility);
ivOptionDResult.setVisibility(visibility);
}
private void setOptionLabelsVisibility(int visibility) {
tvOptionALabel.setVisibility(visibility);
tvOptionBLabel.setVisibility(visibility);
tvOptionCLabel.setVisibility(visibility);
tvOptionDLabel.setVisibility(visibility);
}
private void setOptionSelected(Question.DataBean data, String label) {
TextView labelView = null;
boolean isSelected = false;
switch (label) {
case "A":
labelView = tvOptionALabel;
isSelected = data.isSelectA();
break;
case "B":
labelView = tvOptionBLabel;
isSelected = data.isSelectB();
break;
case "C":
labelView = tvOptionCLabel;
isSelected = data.isSelectC();
break;
case "D":
labelView = tvOptionDLabel;
isSelected = data.isSelectD();
break;
}
if (labelView != null) {
if (isSelected) {
labelView.setBackgroundResource(R.drawable.bg_shape_question_selected);
labelView.setTextColor(Color.WHITE);
} else {
labelView.setBackgroundResource(R.drawable.bg_shape_question_unselected);
labelView.setTextColor(Color.BLACK);
}
}
}
}
},在点击交卷的时候跳转package com.weishitech.jtwzjiaotongcx.fragment.lilv;
import android.view.View;
import com.weishitech.jtwzjiaotongcx.adtakubase.activity.BaseBindActivity;
import com.weishitech.jtwzjiaotongcx.databinding.ActivityDetailsBinding;
import com.weishitech.jtwzjiaotongcx.utils.OnMultiClickListener;
public class DetailsActivity extends BaseBindActivity<ActivityDetailsBinding> {
@Override
protected void init() {
mBinding.ivBack.setOnClickListener(new OnMultiClickListener() {
@Override
public void onMultiClick(View v) {
finish();
}
});
}
}这个页面,显示1-100数字白色未填写,蓝色正确,红色错误,所有题目均可点击查看参考答案
最新发布