图片上加标签labelview

LabelView是一款用于在Android视图上轻松添加标签的开源库。它支持多种视图类型,如ImageView、Button和TextView,并提供了丰富的自定义选项来调整标签样式。通过简单的XML配置或Java代码即可实现。

https://github.com/linger1216/labelview

Sometimes, we need to show a label above an ImageView or any other views. Well, LabelXXView will be able to help you. It's easy to implement as well!

Import your project

Gradle

Step 1. Add the JitPack repository to your build file

Add it in your root build.gradle at the end of repositories:

allprojects {
    repositories {
        ...
        maven { url "https://jitpack.io" }
    }
}


Step 2. Add the dependency

dependencies {
    compile 'com.github.linger1216:labelview:v1.1.0'
}


Maven

Step 1. Add the JitPack repository to your build file

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

Step 2. Add the dependency

<dependency>
    <groupId>com.github.linger1216</groupId>
    <artifactId>labelview</artifactId>
    <version>v1.1.0</version>
</dependency>


Or Manual

Copy all java files and attr.xml into your project.


Create a Label

put xml code in you layout, like follows.

LabelButtonView

<com.lid.lib.LabelButtonView
    android:id="@+id/labelbutton"
    android:layout_width="200dp"
    android:layout_height="48dp"
    android:background="#03a9f4"
    android:gravity="center"
    android:text="Button"
    android:textColor="#ffffff"
    app:label_backgroundColor="#C2185B"
    app:label_distance="20dp"
    app:label_height="20dp"
    app:label_orientation="RIGHT_TOP"
    app:label_text="HD"
    app:label_textSize="12sp" />

LabelImageView

<com.lid.lib.LabelImageView
    android:id="@+id/image1"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:scaleType="centerCrop"
    android:src="@mipmap/image1"
    app:label_backgroundColor="#C2185B"
    app:label_orientation="LEFT_TOP"
    app:label_text="CHINA" />

LabelTextView

<com.lid.lib.LabelTextView
    android:id="@+id/text"
    android:layout_width="wrap_content"
    android:layout_height="48dp"
    android:layout_gravity="center"
    android:layout_marginTop="8dp"
    android:background="#212121"
    android:gravity="center"
    android:padding="16dp"
    android:text="TextView"
    android:textColor="#ffffff"
    app:label_backgroundColor="#03A9F4"
    app:label_distance="15dp"
    app:label_orientation="LEFT_TOP"
    app:label_text="POP"
    app:label_textSize="10sp" />

Parameter Description

If you need Label in your custom View

  1. create an new view class extends YourView
  2. use LabelViewHelper as your Member objects
  3. In Constructor function and onDraw function call LabelViewHelper method.
  4. Call the LabelViewHelper method in other functions

like as follows:

public class LabelXXXView extends YourView {
    LabelViewHelper utils;
    public LabelXXXView(Context context) {
        this(context, null);
    }
    public LabelXXXView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public LabelXXXView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        utils = new LabelViewHelper(context, attrs, defStyleAttr);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        utils.onDraw(canvas, getMeasuredWidth(), getMeasuredHeight());
    }
    public void setLabelHeight(int height) {
        utils.setLabelHeight(this, height);
    }
    public int getLabelHeight() {
        return utils.getLabelHeight();
    }
    public void setLabelDistance(int distance) {
        utils.setLabelDistance(this, distance);
    }
    public int getLabelDistance() {
        return utils.getLabelDistance();
    }
    public boolean isLabelVisual() {
        return utils.isLabelVisual();
    }
    public void setLabelVisual(boolean enable) {
        utils.setLabelVisual(this, enable);
    }
    public int getLabelOrientation() {
        return utils.getLabelOrientation();
    }
    public void setLabelOrientation(int orientation) {
        utils.setLabelOrientation(this, orientation);
    }
    public int getLabelTextColor() {
        return utils.getLabelTextColor();
    }
    public void setLabelTextColor(int textColor) {
        utils.setLabelTextColor(this, textColor);
    }
    public int getLabelBackgroundColor() {
        return utils.getLabelBackgroundColor();
    }
    public void setLabelBackgroundColor(int backgroundColor) {
        utils.setLabelBackgroundColor(this, backgroundColor);
    }
    public String getLabelText() {
        return utils.getLabelText();
    }
    public void setLabelText(String text) {
        utils.setLabelText(this, text);
    }
    public int getLabelTextSize() {
        return utils.getLabelTextSize();
    }
    public void setLabelTextSize(int textSize) {
        utils.setLabelTextSize(this, textSize);
    }
}
List<String> complaintTypeList = new ArrayList<>(); public List<String> getComplaintTypeList(){ complaintTypeList.clear(); complaintTypeList.add("虚假广告"); complaintTypeList.add("广告内容违规"); complaintTypeList.add("广告重复骚扰"); complaintTypeList.add("广告质量差"); complaintTypeList.add("不感兴趣"); return complaintTypeList; }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); } } } } }在点击交卷的时候保存未答、已答、答错数据
12-31
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数字白色未填写,蓝色正确,红色错误,所有题目均可点击查看参考答案
最新发布
12-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值