安卓案例:标准化测试

一、功能需求

  1. 包含单选、多选和判断题题型
  2. 每次考完立刻判分,给出评语

二、标准化测试

(一)运行效果

在这里插入图片描述

(二)涉及知识点

  1. 线性布局(LinearLayout)
  2. 帧式布局(FrameLayout)
  3. 标签(TextView)
  4. 按钮(Button)
  5. 单选按钮(RadioButton)
  6. 复选框(CheckBox)

(三)实现步骤

1、创建安卓应用【StandardTest】

在这里插入图片描述
在这里插入图片描述

2、将背景图片拷贝到drawable目录

在这里插入图片描述

3、主布局资源文件activity_main.xml

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    android:orientation="vertical"
    android:padding="15dp"
    tools:context="net.hw.standard_test.MainActivity">

    <TextView
        android:id="@+id/tv_stem"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2.5"
        android:textSize="20sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:background="#aaaaaa" />

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="4">

        <LinearLayout
            android:id="@+id/ll_single_choice"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:visibility="invisible">

            <RadioGroup
                android:id="@+id/rg_single_choice"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <RadioButton
                    android:id="@+id/rb_single_a"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="20sp" />

                <RadioButton
                    android:id="@+id/rb_single_b"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="20sp" />

                <RadioButton
                    android:id="@+id/rb_single_c"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="20sp" />

                <RadioButton
                    android:id="@+id/rb_single_d"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="20sp" />

            </RadioGroup>

        </LinearLayout>

        <LinearLayout
            android:id="@+id/ll_multiple_choice"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:visibility="invisible">

            <CheckBox
                android:id="@+id/cb_multiple_a"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20sp" />

            <CheckBox
                android:id="@+id/cb_multiple_b"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20sp" />

            <CheckBox
                android:id="@+id/cb_multiple_c"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20sp" />

            <CheckBox
                android:id="@+id/cb_multiple_d"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20sp" />

        </LinearLayout>

        <LinearLayout
            android:id="@+id/ll_judgement"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:visibility="invisible">

            <RadioGroup
                android:id="@+id/rg_judgement"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <RadioButton
                    android:id="@+id/rb_judgement_t"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/judgement_t"
                    android:textSize="20sp" />

                <RadioButton
                    android:id="@+id/rb_judgement_f"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/judgement_f"
                    android:textSize="20sp" />
            </RadioGroup>
        </LinearLayout>
    </FrameLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:background="#aaaaaa" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_previous"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:onClick="doPrevious"
            android:text="@string/previous"
            android:textSize="20sp" />

        <Button
            android:id="@+id/btn_next"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:onClick="doNext"
            android:text="@string/next"
            android:textSize="20sp" />

        <Button
            android:id="@+id/btnSubmit"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:onClick="doSubmit"
            android:text="@string/submit"
            android:textSize="20sp" />

        <Button
            android:id="@+id/btn_exit"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:onClick="doExit"
            android:text="@string/exit"
            android:textSize="20sp" />
    </LinearLayout>
</LinearLayout>

4、字符串资源文件strings.xml

在这里插入图片描述

<string name="judgement_t">正确</string>
    <string name="judgement_f">错误</string>
    <string name="previous">上一题</string>
    <string name="next">下一题</string>
    <string name="submit">提交</string>
    <string name="exit">退出</string>

5、创建试题实体类 - Question

在这里插入图片描述

package net.hw.standard_test;

/**
 * 功能:试题实体类
 * 作者:华卫
 * 日期:2020年10月20日
 */
public class Question {
    
    
    /**
     * 编号
     */
    private int id;
    /**
     * 题干
     */
    private String stem;
    /**
     * A选项
     */
    private String a;
    /**
     * B选项
     */
    private String b;
    /**
     * C选项
     */
    private String c;
    /**
     * D选项
     */
    private String d;
    /**
     * 题型
     * 1 - 单选题
     * 2 - 多选题
     * 3 - 判断题
     */
    private int type;
    /**
     * 答案
     */
    private String answer;

    public int getId() {
    
    
        return id;
    }

    public void setId(int id) {
    
    
        this.id = id;
    }

    public String getStem() {
    
    
        return stem;
    }

    public void setStem(String stem) {
    
    
        this.stem = stem;
    }

    public String getA() {
    
    
        return a;
    }

    public void setA(String a) {
    
    
        this.a = a;
    }

    public String getB() {
    
    
        return b;
    }

    public void setB(String b) {
    
    
        this.b = b;
    }

    public String getC() {
    
    
        return c;
    }

    public void setC(String c) {
    
    
        this.c = c;
    }

    public String getD() {
    
    
        return d;
    }

    public void setD(String d) {
    
    
        this.d = d;
    }

    public int getType() {
    
    
        return type;
    }

    public void setType(int type) {
    
    
        this.type = type;
    }

    public String getAnswer() {
    
    
        return answer;
    }

    public void setAnswer(String answer) {
    
    
        this.answer = answer;
    }

    @Override
    public String toString() {
    
    
        return "Question{" +
                "id=" + id +
                ", stem='" + stem + '\'' +
                ", a='" + a + '\'' +
                ", b='" + b + '\'' +
                ", c='" + c + '\'' +
                ", d='" + d + '\'' +
                ", type=" + type +
                ", answer='" + answer + '\'' +
                '}';
    }
}

6、主界面类MainActivity

在这里插入图片描述

package net.hw.standard_test;

import android.app.AlertDialog;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    
    

    private LinearLayout llSingleChoice;
    private LinearLayout llMultipleChoice;
    private LinearLayout llJudgement;

    private TextView tvStem;

    private RadioGroup rgSingleChoice;
    private RadioButton rbSingleA;
    private RadioButton rbSingleB;
    private RadioButton rbSingleC;
    private RadioButton rbSingleD;

    private RadioGroup rgJudgement;
    private RadioButton rbJudgementT;
    private RadioButton rbJudgementF;

    private CheckBox cbMultipleA;
    private CheckBox cbMultipleB;
    private CheckBox cbMultipleC;
    private CheckBox cbMultipleD;

    private ArrayList<Question> questions;

    private int questionIndex;

    private String[] answers;

    private String answer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        // 利用布局资源文件设置用户界面
        setContentView(R.layout.activity_main);

        // 通过资源标识符获得控件实例
        llSingleChoice = findViewById(R.id.ll_single_choice);
        llMultipleChoice = findViewById(R.id.ll_multiple_choice);
        llJudgement = findViewById(R.id.ll_judgement);
        tvStem = findViewById(R.id.tv_stem);
        rgSingleChoice = findViewById(R.id.rg_single_choice);
        rbSingleA = findViewById(R.id.rb_single_a);
        rbSingleB = findViewById(R.id.rb_single_b);
        rbSingleC = findViewById(R.id.rb_single_c);
        rbSingleD = findViewById(R.id.rb_single_d);
        rgJudgement = findViewById(R.id.rg_judgement);
        rbJudgementT = findViewById(R.id.rb_judgement_t);
        rbJudgementF = findViewById(R.id.rb_judgement_f);
        cbMultipleA = findViewById(R.id.cb_multiple_a);
        cbMultipleB = findViewById(R.id.cb_multiple_b);
        cbMultipleC = findViewById(R.id.cb_multiple_c);
        cbMultipleD = findViewById(R.id.cb_multiple_d);

        // 初始化试题库
        questions = getQuestions();

        // 实例化答案数组
        answers = new String[questions.size()];

        // 取出第1题
        Question question = questions.get(questionIndex);
        // 根据题型设置界面
        setInterfaceByType(question);
    }

    /**
     * 获取试题列表
     *
     * @return 试题列表
     */
    private ArrayList<Question> getQuestions() {
    
    
        ArrayList<Question> questions = new ArrayList<>();

        // 创建第1题
        Question question = new Question();
        question.setId(1);
        question.setStem("驾驶机动车在道路上违反道路交通安全法的行为,属于什么行为?");
        question.setA("违章行为");
        question.setB("违法行为");
        question.setC("过失行为");
        question.setD("违规行为");
        question.setType(1);
        question.setAnswer("B");
        // 将第1题添加到试题库
        questions.add(question);

        // 创建第2题
        question = new Question();
        question.setId(2);
        question.setStem("交通信号包括交通信号灯、交通标志、交通标线和交通警察的指挥。");
        question.setA("正确");
        question.setB("错误");
        question.setC("");
        question.setD("");
        question.setType(3);
        question.setAnswer("A");
        // 将第2题添加到试题库
        questions.add(question);

        // 创建第3题
        question = new Question();
        question.setId(3);
        question.setStem("机动车驾驶人违法驾驶造成重大交通事故构成犯罪的,依法追究什么责任?");
        question.setA("刑事责任");
        question.setB("民事责任");
        question.setC("经济责任");
        question.setD("直接责任");
        question.setType(1);
        question.setAnswer("A");
        // 将第3题添加到试题库
        questions.add(question);

        // 创建第4题
        question = new Question();
        question.setId(4);
        question.setStem("钱某驾驶大型卧铺客车,乘载45人(核载40人),保持40公里/小时以上的车速行至八宿县境内连续下坡急转弯路段处,翻下100米深的山崖,造成17人死亡、20人受伤。钱某的主要违法行为是什么?");
        question.setA("驾驶时接听手持电话");
        question.setB("超速行驶");
        question.setC("客车超员");
        question.setD("疲劳驾驶");
        question.setType(2);
        question.setAnswer("BC");
        // 将第4题添加到试题库
        questions.add(question);

        // 创建第5题
        question = new Question();
        question.setId(5);
        question.setStem("邹某驾驶大型卧铺客车(核载35人,实载47人),行至京港澳高速公路938公里时,因乘车人携带的大量危险化学品在车厢内突然发生爆燃,造成41人死亡,6人受伤。此事故中的主要违法行为是什么?");
        question.setA("客车超员");
        question.setB("乘车人携带易燃易爆危险物品");
        question.setC("超速行驶");
        question.setD("不按规定停车");
        question.setType(2);
        question.setAnswer("AB");
        // 将第5题添加到试题库
        questions.add(question);

        return questions;
    }

    /**
     * 根据题型设置界面
     *
     * @param question
     */
    private void setInterfaceByType(Question question) {
    
    
        // 判断题型,选择界面
        switch (question.getType()) {
    
    
            case 1:
                llSingleChoice.setVisibility(View.VISIBLE);
                llMultipleChoice.setVisibility(View.INVISIBLE);
                llJudgement.setVisibility(View.INVISIBLE);
                tvStem.setText("[单选] " + question.getId() + ". " + question.getStem());
                tvStem.setTextColor(Color.RED);
                rbSingleA.setText(question.getA());
                rbSingleB.setText(question.getB());
                rbSingleC.setText(question.getC());
                rbSingleD.setText(question.getD());

                // 清空控件选中状态
                rbSingleA.setChecked(false);
                rbSingleB.setChecked(false);
                rbSingleC.setChecked(false);
                rbSingleD.setChecked(false);
                rgSingleChoice.check(-1);

                answer = answers[questionIndex];
                if (answer != null) {
    
    
                    // 根据用户答案来设定单选按钮状态
                    switch (answer) {
    
    
                        case "A":
                            rbSingleA.setChecked(true);
                            break;
                        case "B":
                            rbSingleB.setChecked(true);
                            break;
                        case "C":
                            rbSingleC.setChecked(true);
                            break;
                        case "D":
                            rbSingleD.setChecked(true);
                            break;
                    }
                }
                break;
            case 2:
                llMultipleChoice.setVisibility(View.VISIBLE);
                llSingleChoice.setVisibility(View.INVISIBLE);
                llJudgement.setVisibility(View.INVISIBLE);
                tvStem.setText("[多选] " + question.getId() + ". " + question.getStem());
                tvStem.setTextColor(Color.BLACK);
                cbMultipleA.setText(question.getA());
                cbMultipleB.setText(question.getB());
                cbMultipleC.setText(question.getC());
                cbMultipleD.setText(question.getD());

                // 清空控件选中状态
                cbMultipleA.setChecked(false);
                cbMultipleB.setChecked(false);
                cbMultipleC.setChecked(false);
                cbMultipleD.setChecked(false);

                answer = answers[questionIndex];
                if (answer != null) {
    
    
                    for (int i = 0; i < answer.length(); i++) {
    
    
                        switch (answer.charAt(i)) {
    
    
                            case 'A':
                                cbMultipleA.setChecked(true);
                                break;
                            case 'B':
                                cbMultipleB.setChecked(true);
                                break;
                            case 'C':
                                cbMultipleC.setChecked(true);
                                break;
                            case 'D':
                                cbMultipleD.setChecked(true);
                                break;
                        }
                    }
                }

                break;
            case 3:
                llJudgement.setVisibility(View.VISIBLE);
                llSingleChoice.setVisibility(View.INVISIBLE);
                llMultipleChoice.setVisibility(View.INVISIBLE);
                tvStem.setText("[判断] " + question.getId() + ". " + question.getStem());
                tvStem.setTextColor(Color.BLUE);

                // 清空控件选中状态
                rbJudgementT.setChecked(false);
                rbJudgementF.setChecked(false);
                rgJudgement.check(-1);

                // 根据用户答案来设定单选按钮状态
                answer = answers[questionIndex];
                if (answer != null) {
    
    
                    switch (answer) {
    
    
                        case "A":
                            rbJudgementT.setChecked(true);
                            break;
                        case "B":
                            rbJudgementF.setChecked(true);
                            break;
                    }
                }
        }
    }


    /**
     * 退出
     *
     * @param view
     */

    public void doExit(View view) {
    
    
        finish();
    }

    /**
     * 上一题
     *
     * @param view
     */
    public void doPrevious(View view) {
    
    
        // 判断用户是否做了本题
        switch (questions.get(questionIndex).getType()) {
    
    
            case 1:
                if (rbSingleA.isChecked() || rbSingleB.isChecked() || rbSingleC.isChecked() || rbSingleD.isChecked()) {
    
    
                    saveAnswer();
                }
                break;
            case 2:
                if (cbMultipleA.isChecked() || cbMultipleB.isChecked() || cbMultipleC.isChecked() || cbMultipleD.isChecked()) {
    
    
                    saveAnswer();
                }
                break;
            case 3:
                if (rbJudgementT.isChecked() || rbJudgementF.isChecked()) {
    
    
                    saveAnswer();
                }
                break;
        }

        if (questionIndex > 0) {
    
    
            questionIndex--;
        } else {
    
    
            questionIndex = questions.size() - 1;
        }

        // 根据题型设置界面
        setInterfaceByType(questions.get(questionIndex));
    }

    /**
     * 下一题
     *
     * @param view
     */
    public void doNext(View view) {
    
    
        // 判断用户是否做了本题
        switch (questions.get(questionIndex).getType()) {
    
    
            case 1:
                if (rbSingleA.isChecked() || rbSingleB.isChecked() || rbSingleC.isChecked() || rbSingleD.isChecked()) {
    
    
                    saveAnswer();
                }
                break;
            case 2:
                if (cbMultipleA.isChecked() || cbMultipleB.isChecked() || cbMultipleC.isChecked() || cbMultipleD.isChecked()) {
    
    
                    saveAnswer();
                }
                break;
            case 3:
                if (rbJudgementT.isChecked() || rbJudgementF.isChecked()) {
    
    
                    saveAnswer();
                }
                break;
        }

        Log.d("test", (questionIndex + 1) + answers[questionIndex]);

        if (questionIndex < questions.size() - 1) {
    
    
            questionIndex++;
        } else {
    
    
            questionIndex = 0;
        }
        // 根据题型设置界面
        setInterfaceByType(questions.get(questionIndex));
    }

    /**
     * 提交按钮单击事件处理方法
     *
     * @param view
     */
    public void doSubmit(View view) {
    
    
        // 保存当前题目答案
        saveAnswer();

        // 计算成绩点
        int points = 0;
        for (int i = 0; i < questions.size(); i++) {
    
    
            if (null != answers[i]) {
    
    
                if (answers[i].equals(questions.get(i).getAnswer())) {
    
    
                    points++;
                }
            }
        }

        // 按百分制来折算分数
        double score = points * 100 / questions.size();

        // 根据分数给出评语
        String comment = "";
        if (score >= 90) {
    
    
            comment = "分数:" + score + "\n评语:棒棒哒~";
        } else if (score >=60) {
    
    
            comment = "分数:" + score + "\n评语:还行吧!";
        } else {
    
    
            comment = "分数:" + score + "\n评语:好好干吧!";
        }

        // 利用警告对话框来显示测试结果
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setIcon(R.mipmap.ic_launcher_round)
                .setTitle("测试结果")
                .setMessage(comment)
                .setPositiveButton("确定", null)
                .create()
                .show();
    }

    /**
     * 保存用户选择的答案
     */
    private void saveAnswer() {
    
    
        switch (questions.get(questionIndex).getType()) {
    
    
            case 1: // 单选题
                if (rbSingleA.isChecked()) {
    
    
                    answers[questionIndex] = "A";
                } else if (rbSingleB.isChecked()) {
    
    
                    answers[questionIndex] = "B";
                } else if (rbSingleC.isChecked()) {
    
    
                    answers[questionIndex] = "C";
                } else {
    
    
                    answers[questionIndex] = "D";
                }
                break;
            case 2: // 多选题
                StringBuilder builder = new StringBuilder();
                if (cbMultipleA.isChecked()) {
    
    
                    builder.append("A");
                }
                if (cbMultipleB.isChecked()) {
    
    
                    builder.append("B");
                }
                if (cbMultipleC.isChecked()) {
    
    
                    builder.append("C");
                }
                if (cbMultipleD.isChecked()) {
    
    
                    builder.append("D");
                }
                answers[questionIndex] = builder.toString();
                break;
            case 3: // 判断题
                if (rbJudgementT.isChecked()) {
    
    
                    answers[questionIndex] = "A";
                } else {
    
    
                    answers[questionIndex] = "B";
                }
                break;
        }
    }
}

7、启动应用,查看效果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/howard2005/article/details/109177157