由于毕业设计的需要,本人自学了Android的开发,做了一款基于Android的课程网上学习系统。可以实现课程在线观看,发布通知,签到定位,在线测试等功能。但毕竟本人不是专业的软件专业,因而整个系统和程序中也会存在很多不足,而且,这也是我第一次在CSDN上写这种博客,所以对于不足之处,欢迎大家提出指导意见,批评指正。写这篇博客,主要是因为在软件的设计中,也会遇到很多的问题,但通过在网上查阅资料,得到了很多的帮助,因而希望也能写一篇博客,给大家一些参考,帮助到有需要的人,同时,也是对自己的开发的一个记录。
之前已经对“签到定位”进行了一个介绍:https://blog.csdn.net/qq_28053421/article/details/105788953。接下来继续对“在线测试”功能进行记录。
在线测试 功能简介在线测试想必大家也都很熟悉,这里主要是两个方面:老师发布测试,学生进行测试。测试主要分为两类:作业和考试。考试是有一个考试时间的,并且只有一次考试机会。
功能实现 老师发布测试的部分发布测试的界面如下(这是直接在layout布局预览里截图出来的,所以里面会有ListView的item的显示):
点击”添加题目“后,进入添加题目的界面:
在这里,我们要进行一个题目类型的判断,如,用户选择的单选题,那么就只能勾选一个正确选项,多选题,则要勾选两个及以上的选项,同时,也要对正确答案进行一个拼接,以方便存入数据库。在添加题目时,我将题目都存在了本地的SQLite数据库里,这样可以随时查看添加的题目,在点击发布题目后,会将本地数据库的题目数据也删除。主要代码如下:
package com.sjhbysj.aixuexi.activities;
import java.io.Serializable;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Messenger;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.Toast;
import com.sjhbysj.aixuexi.R;
import com.sjhbysj.aixuexi.config.Constants;
import com.sjhbysj.aixuexi.domain.Question;
import com.sjhbysj.aixuexi.service.TestService;
import com.sjhbysj.aixuexi.utils.MyXUtils;
public class AddQuestionActivity extends Activity {
private RadioGroup rg_addquestion_type; //题目类型
private EditText et_addquestion_question; //题干
private CheckBox cb_addquestion_select_1; //选择框 1
private CheckBox cb_addquestion_select_2; //选择框 2
private CheckBox cb_addquestion_select_3; //选择框 3
private EditText et_addquestion_answer_1; //答案选项1
private EditText et_addquestion_answer_2; //答案选项2
private EditText et_addquestion_answer_3; //答案选项3
private EditText et_addquestion_grade; //题目分数
private Button btn_addquestion_ok; //确认按钮
private Button btn_addquestion_delete; //删除按钮
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case Constants.ADD_QUESTION_SUCCESS:
//添加题目成功---则自动返回上一个页面,并让上一页刷新数据
setResult(Constants.CHANGE_QUESTION);
finish();
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_addquestion);
initView();
initData();
initListener();
}
private void initListener() {
//为 题目类型 设置一个监听,当选择类型为 选择题 时,自动填充答案选项。
rg_addquestion_type.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if(checkedId == R.id.rb_addquestion_judgment){
//选择题目类型为选择题
et_addquestion_answer_1.setText("对");
et_addquestion_answer_2.setText("错");
//为防止之前对第三个选项做过设置
et_addquestion_answer_3.setText(""); //将第三个选项清空
cb_addquestion_select_3.setChecked(false); //将第三个选项的勾选也去掉
//在将第三个选项给隐藏
et_addquestion_answer_3.setVisibility(View.GONE);
cb_addquestion_select_3.setVisibility(View.GONE);
}else{
//显示第三个选项
et_addquestion_answer_3.setVisibility(View.VISIBLE);
cb_addquestion_select_3.setVisibility(View.VISIBLE);
}
}
});
//设置确认按钮的监听
btn_addquestion_ok.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dealData(); //处理用户输入的数据
}
});
}
private void initData() {
}
private void initView() {
...... //初始化控件
//这是用户添加题目的,没有删除功能,但因为和查看问题详情共用一个页面,所以这里让按钮不显示出来
btn_addquestion_delete.setVisibility(View.GONE);
}
private void dealData() {
boolean etState = false; //判断所有EditText是否填写完整的标志位
boolean cbState = false; //判断所有CheckBox是否填写完整的标志位
int typeId = rg_addquestion_type.getCheckedRadioButtonId();
String type = "单选题"; //默认选择
if(typeId == R.id.rb_addquestion_multichoice){
type = "多选题";
}else if(typeId == R.id.rb_addquestion_judgment){
type = "判断题";
}
String question = et_addquestion_question.getText().toString().trim();
String answer_1 = et_addquestion_answer_1.getText().toString().trim();
String answer_2 = et_addquestion_answer_2.getText().toString().trim();
String answer_3 = et_addquestion_answer_3.getText().toString().trim();
String grade = et_addquestion_grade.getText().toString().trim();
String answer = ""; //正确答案--开始为空
//判断EditText输入框
//判断所有要输入的 输入框
if("判断题".equals(type)){
//为判断题,则答案选项中 只需要输入 前两个选项 就可以,即 选项三 的输入框不用填
//判断输入框
if(!TextUtils.isEmpty(grade) && !TextUtils.isEmpty(question) && !TextUtils.isEmpty(answer_1) &&
!TextUtils.isEmpty(answer_2)){
//说明 输入框都已 填写
etState = true; //更改EditText状态
//判断CheckBox 选择框----只有一个选择框框能被选中,并且第三个不能选
if((cb_addquestion_select_1.isChecked() && !cb_addquestion_select_2.isChecked() && !cb_addquestion_select_3.isChecked()) ||
(!cb_addquestion_select_1.isChecked() && cb_addquestion_select_2.isChecked() && !cb_addquestion_select_3.isChecked())){
//说明选择满足要求
cbState = true; //更改CheckBox状态
//获得正确答案
if(cb_addquestion_select_1.isChecked()){
//选择的 选项1---即 A
answer = cb_addquestion_select_1.getText().toString().trim();
}else if(cb_addquestion_select_2.isChecked()){
//选择的 选项2---即 B
answer = cb_addquestion_select_2.getText().toString().trim();
}
}else{
Toast.makeText(AddQuestionActivity.this, "请勾选出正确选项,选择题只能勾选一个正确项", 0).show();
}
}else{
Toast.makeText(AddQuestionActivity.this, "您还有输入框没有填写哦", 0).show();
}
}else{
//说明为选择题,则三个选项都要填写
//判断输入框
if(!TextUtils.isEmpty(grade) && !TextUtils.isEmpty(question) && !TextUtils.isEmpty(answer_1) &&
!TextUtils.isEmpty(answer_2) && !TextUtils.isEmpty(answer_3)){
//说明 输入框都已 填写
etState = true; //更改EditText状态
if("单选题".equals(type)){
//为单选题,则只能有 一个 选择框 被选中
if((cb_addquestion_select_1.isChecked() && !cb_addquestion_select_2.isChecked() && !cb_addquestion_select_3.isChecked()) ||
(!cb_addquestion_select_1.isChecked() && cb_addquestion_select_2.isChecked() && !cb_addquestion_select_3.isChecked()) ||
(!cb_addquestion_select_1.isChecked() && !cb_addquestion_select_2.isChecked() && cb_addquestion_select_3.isChecked())){
//说明选择满足要求
cbState = true; //更改CheckBox状态
//获得正确答案
if(cb_addquestion_select_1.isChecked()){
//选择的 选项1---即A
answer = cb_addquestion_select_1.getText().toString().trim();
}else if(cb_addquestion_select_2.isChecked()){
//选择的 选项2---即B
answer = cb_addquestion_select_2.getText().toString().trim();
}else if(cb_addquestion_select_3.isChecked()){
//选择的 选项3---即C
answer = cb_addquestion_select_3.getText().toString().trim();
}
}else{
Toast.makeText(AddQuestionActivity.this, "请勾选出正确选项,单选题只能勾选一个正确项", 0).show();
}
}else{
//为多选题,则 要有 两个及以上 的 选择框 被选中
if((cb_addquestion_select_1.isChecked() && cb_addquestion_select_2.isChecked() && !cb_addquestion_select_3.isChecked()) || //选择:A B
(cb_addquestion_select_1.isChecked() && !cb_addquestion_select_2.isChecked() && cb_addquestion_select_3.isChecked()) || //选择:A C
(!cb_addquestion_select_1.isChecked() && cb_addquestion_select_2.isChecked() && cb_addquestion_select_3.isChecked()) || //选择:B C
(cb_addquestion_select_1.isChecked() && cb_addquestion_select_2.isChecked() && cb_addquestion_select_3.isChecked())){ //选择:A B C
//说明选择满足要求
cbState = true; //更改CheckBox状态
//多选获得的答案为 类似 AB 型,表示答案为A和B,后期可根据该特定规律进行字符切割
if(cb_addquestion_select_1.isChecked()){
//选项1被选中了
answer += cb_addquestion_select_1.getText().toString().trim();
}
if(cb_addquestion_select_2.isChecked()){
//选项2被选中了
answer += cb_addquestion_select_2.getText().toString().trim();
}
if(cb_addquestion_select_3.isChecked()){
//选项3被选中了
answer += cb_addquestion_select_3.getText().toString().trim();
}
}else{
Toast.makeText(AddQuestionActivity.this, "请勾选出正确选项,多选题需勾选两个及以上正确项", 0).show();
}
}
}else{
Toast.makeText(AddQuestionActivity.this, "您还有输入框没有填写哦", 0).show();
}
}
//确定按钮做最终判断
if(etState && cbState){
//说明全部都已填写完成
//为该题设置题号
//说明要添加一道题---则题号+1
TestService.titleNumber++;
//处理数据---写入本地数据库
Question questionBean = new Question("question-"+MyXUtils.generateUUID(), null, TestService.titleNumber+"", type, question, answer_1, answer_2, answer_3, answer, grade);
//启动服务
Intent service = new Intent(AddQuestionActivity.this, TestService.class);
service.putExtra("operation", "addQuestion");
service.putExtra("questionBean", (Serializable)questionBean);
service.putExtra("messenger", new Messenger(handler));
startService(service);
//恢复标志位
etState = false;
cbState = false;
}
}
}
在添加题目的页面点击确定后,会将题目存入本地数据库,然后自动返回上一个页面,并刷新数据。如图:
当题目都添加完成后,点击“发布测试”,会先检查数据的填写情况,当填写无误后,就将数据发送到服务端并存入数据库,数据以json字符串形式发送
//发布测试 按钮的监听
btn_createtest_release.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//检查所有项目是否都已填写
if(TestService.questions.size() == 0){
//说明还没有添加题目
Toast.makeText(CreateTestActivity.this, "您还没有添加题目", 0).show();
return;
}
String name = et_createtest_testname.getText().toString().trim();
if(TextUtils.isEmpty(name)){
Toast.makeText(CreateTestActivity.this, "请填写测试名称", 0).show();
return;
}
String examTime = null;
String testType = "作业"; //默认选择的为作业
//如果选择的考试,则需要填写考试时间
if(rg_createtest_testtype.getCheckedRadioButtonId() == R.id.rb_createtest_exam){
//选择的为 考试
testType = "考试";
//需要填写考试时间
examTime = et_createtest_examtime.getText().toString().trim();
if(TextUtils.isEmpty(examTime)){
Toast.makeText(CreateTestActivity.this, "请填写考试时间", 0).show();
return;
}
}
if(!deadlineSelected){ //默认为false,当选择了日期后变为true
//说明提交截止日期还没有选择
Toast.makeText(CreateTestActivity.this, "请选择截止日期", 0).show();
return;
}
//到这里,说明都已填写,可以提交
//封装数据
Test test = new Test();
test.setName(name);
test.setQuestionCount(TestService.questions.size()+"");
test.setType(testType);
//遍历题目,计算总分
int sumGrade = 0;
for (Question q : TestService.questions) {
int grade = Integer.parseInt(q.getGrade());
sumGrade += grade;
}
test.setGrade(sumGrade+"");
test.setDeadline(deadline);
if("考试".equals(testType)){
test.setExamTime(examTime);
}
test.setReleaseClass(mClass.getJoinClassCode());
//显示 正在发布 进度条
showReleaseingDialog();
//启动服务,发布测试
Intent service = new Intent(CreateTestActivity.this, TestService.class);
service.putExtra("operation", "releaseTest");
service.putExtra("test", (Serializable)test);
service.putExtra("messenger", new Messenger(handler));
startService(service);
}
});
学生在线测试部分
学生在“测试列表”页面可以看到所有已发布的测试和提交信息,这里同样是使用的一个ListView来进行显示,当点击里面的一个item后,就可以进入该测试。至于“已提交”和“未提交”的判断,我是先在服务端数据库里建了一个表(student_scores),这个表主要用于存储学生的测试得分,然后,在进入“测试列表”页面时,我会根据用户名(username)去请求这个表中 该用户的 所有的测试提交信息,然后遍历提交信息,根据测试的id(testId)判断有没有提交某一个测试
序号 | 列名 | 数据类型 | 说明 |
---|---|---|---|
1 | username | varchar | 用户名 |
2 | testId | varchar | 测试的id号 |
3 | score | varchar | 测试得分 |
4 | answerTime | timestamp | 测试时间,系统自动维护 |
学生进入某一个测试后,系统先会判断该测试是否已经提交了,如果已经提交了,那么进入后显示的是考生的答题情况页面,如图1,如果没有提交过,那么就会判断是否已经过了截止日期,如果过了,那么就不能测试提交,没过的话就可以进行测试。当然,系统还会判断一下测试的类型,如果是考试,那么就会给出提示,让考生注意时间等,并且在确认考试后开始倒计时,测试页面如图2。
学生的答题情况我是简单的先用一个List数组暂存,当提交测试时,直接将这里的数据封装传输。学生进行测试部分的代码如下:
package com.sjhbysj.aixuexi.activities;
import java.io.Serializable;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Messenger;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.sjhbysj.aixuexi.R;
import com.sjhbysj.aixuexi.config.Constants;
import com.sjhbysj.aixuexi.domain.Question;
import com.sjhbysj.aixuexi.domain.StudentAnswer;
import com.sjhbysj.aixuexi.domain.StudentScore;
import com.sjhbysj.aixuexi.domain.Test;
import com.sjhbysj.aixuexi.service.TestService;
import com.sjhbysj.aixuexi.utils.MyXUtils;
import com.sjhbysj.aixuexi.view.CountDown;
import com.sjhbysj.aixuexi.view.CountDown.OnTimeCompleteListener;
public class StudentTestActivity extends Activity {
private TextView tv_studenttest_type;
private CountDown cd_studenttest_countdown;
private TextView tv_studenttest_number;
private TextView tv_studenttest_questiontype;
private TextView tv_studenttest_grade;
private TextView tv_studenttest_question;
private RadioGroup rg_studenttest_select;
private RadioButton rb_studenttest_A;
private RadioButton rb_studenttest_B;
private RadioButton rb_studenttest_C;
private LinearLayout ll_studenttest_cb;
private CheckBox cb_studenttest_A;
private CheckBox cb_studenttest_B;
private CheckBox cb_studenttest_C;
private Button btn_studenttest_last;
private TextView tv_studenttest_currentposition;
private TextView tv_studenttest_totalnumber;
private Button btn_studenttest_next;
private Test test;
private Question currentQuestion; //当前显示的题目
private int currentPosition = 0;
private boolean isFirst = true; //是否第一次答题
private int score = 0; //测试得分
private ProgressDialog dialog;
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case Constants.REQUEST_QUESTION_SUCCESS:
//获得了测试的 试题
//清空 学生的作答 的集合
TestService.studentAnswers.clear();
if("考试".equals(test.getType())){
//弹出提示框,准备倒计时
showExamAlertDialog();
}
//显示第一题题目
showQuestion(currentPosition);
break;
case Constants.CHECK_IN_TEST_SUCCESS:
//交卷完成,跳转到 结果显示 的页面
dialog.dismiss();
Intent intent = new Intent(StudentTestActivity.this, TestResultActivity.class);
intent.putExtra("score", score);
startActivityForResult(intent, Constants.CHANGE_TEST);
break;
case Constants.INTERNET_ERROR:
Toast.makeText(StudentTestActivity.this, "网络错误", 0).show();
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_studenttest);
initView();
initData();
initListener();
}
private void initListener() {
// 上一题的点击按钮
btn_studenttest_last.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//判断是否在第一道题上
if(currentPosition == 0){
//不能再往上翻
Toast.makeText(StudentTestActivity.this, "已经是第一题了", 0).show();
return;
}
//显示上一题
currentPosition--;
showQuestion(currentPosition);
}
});
// 下一题 或 提交测试(当处于最后一道题时) 的点击按钮
btn_studenttest_next.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//判断用户 有没有 去做这道题
if(cb_studenttest_A.isChecked() || cb_studenttest_B.isChecked() || cb_studenttest_C.isChecked() ||
rb_studenttest_A.isChecked() || rb_studenttest_B.isChecked() || rb_studenttest_C.isChecked()){
//说明做了这道题,则判断要执行的操作
if("提交测试".equals(btn_studenttest_next.getText().toString().trim())){
//把 提交按钮 所在页面 的数据存入list集合
dealStudentAnswer();
//判断是否全部的题目都做完了
if(TestService.studentAnswers.size() != TestService.questions.size()){
//没有做完
Toast.makeText(StudentTestActivity.this, "还有题目没有做哦", 0).show();
}else{
//做完了,提交试卷
showloadingDialog("正在交卷");
checkInTest();
}
}else if("下一题".equals(btn_studenttest_next.getText().toString().trim())){
//将这道题做的答案存入list集合
dealStudentAnswer();
//显示下一题
currentPosition++;
showQuestion(currentPosition);
}
}else{
//说明没有做这道题
//判断操作
if("提交测试".equals(btn_studenttest_next.getText().toString().trim())){
//说明是在最后一道题上,但最后一道题没有写,所以提示用户要做 这道题
Toast.makeText(StudentTestActivity.this, "还有题目没有做哦", 0).show();
}else if("下一题".equals(btn_studenttest_next.getText().toString().trim())){
// 不存数据,直接显示下一题
currentPosition++;
showQuestion(currentPosition);
}
}
}
});
//倒计时结束的监听
cd_studenttest_countdown.setOnTimeCompleteListener(new OnTimeCompleteListener() {
@Override
public void onTimeComplete() {
showloadingDialog("考试结束,正在交卷");
checkInTest();
}
});
}
private void checkInTest() {
//计算得分
for (Question question : TestService.questions) {
for (StudentAnswer studentAnswer : TestService.studentAnswers) {
if(studentAnswer.getQuestionId().equals(question.getQuestionId())){
//找到了对应的题目
//判断正误
if(studentAnswer.getStudentAnswer().equals(question.getCorrectAnswer())){
//答案正确
//拿到该题的分数,并计算得分
score += Integer.parseInt(question.getGrade());
}
}
}
}
//封装数据
StudentScore studentScore = new StudentScore(TestService.loginUser.getUserName(), test.getId(), score+"");
//启动服务,提交
Intent service = new Intent(StudentTestActivity.this, TestService.class);
service.putExtra("operation", "checkInTest");
service.putExtra("studentScore", (Serializable)studentScore);
service.putExtra("messenger", new Messenger(handler));
startService(service);
}
private void initData() {
Intent intent = getIntent();
test = (Test) intent.getSerializableExtra("test");
//检查是否已经过了截止日期
String currentTime = MyXUtils.getCurrentTime();
//得到 yyyy-MM-dd HH:mm 型的时间
currentTime = currentTime.substring(0, 16);
//与 截止时间比较--可以先将里面的符号都给删掉,变为存数字的字符串,然后转化比较( .replace("-", "").replace(" ", "").replace(":", "") )
//但实现发现,直接用原始字符串比较也可以得出正确结果
if(currentTime.compareTo(test.getDeadline()) > 0){
//说明已经过了截止时间
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("提示")
.setMessage("该测试已经过了截止提交日期,无法答题")
.setNeutralButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish(); //退出页面
}
});
builder.show();
}
//显示信息
//题目类型
tv_studenttest_type.setText(test.getType());
//倒计时
if("作业".equals(test.getType())){
//不显示倒计时控件
cd_studenttest_countdown.setVisibility(View.GONE);
}else if("考试".equals(test.getType())){
//获得考试时间
int examTime = Integer.parseInt(test.getExamTime());
//将分钟转化为秒
examTime = examTime*60;
//初始化倒计时
cd_studenttest_countdown.initTime(examTime);
}
//总题数
tv_studenttest_totalnumber.setText(test.getQuestionCount());
//启动服务,获取题目
Intent service = new Intent(StudentTestActivity.this, TestService.class);
service.putExtra("operation", "requestQuestion");
service.putExtra("test", (Serializable)test);
service.putExtra("messenger", new Messenger(handler));
startService(service);
}
private void initView() {
...... //控件的初始化
}
private void dealStudentAnswer() {
String sAnswer = "";
boolean updateList = false; //是否更新了 学生作答的 list集合
if("多选题".equals(currentQuestion.getType())){
//拼接答案
if(cb_studenttest_A.isChecked()){
//选项A被选中了
sAnswer += "A:";
}
if(cb_studenttest_B.isChecked()){
//选项B被选中了
sAnswer += "B:";
}
if(cb_studenttest_C.isChecked()){
//选项C被选中了
sAnswer += "C:";
}
}else{
//为 单选 或者 判断
int id = rg_studenttest_select.getCheckedRadioButtonId();
if(id == R.id.rb_studenttest_A){
sAnswer = "A:";
}
if(id == R.id.rb_studenttest_B){
sAnswer = "B:";
}
if(id == R.id.rb_studenttest_C){
sAnswer = "C:";
}
}
//判断答案正误
String isCorrect = "F";
if(sAnswer.equals(currentQuestion.getCorrectAnswer())){
isCorrect = "T";
}
//封装数据
StudentAnswer stuAnswer = new StudentAnswer(TestService.loginUser.getUserName(), currentQuestion.getQuestionId(), test.getId(), sAnswer, isCorrect);
if(isFirst){
//说明为第一次做题---直接将数据加入集合
TestService.studentAnswers.add(stuAnswer);
isFirst = false;
}else{
//说明已经做了题目,即集合里有数据了,可以遍历集合。当集合为空时,不会执行遍历函数
StudentAnswer studentAnswer = new StudentAnswer();
//遍历 学生已作答的list集合 ,看这道题之前有没有写过---如果写过,则更新数据
for (int i = 0; i < TestService.studentAnswers.size(); i++) {
studentAnswer = TestService.studentAnswers.get(i);
if(studentAnswer.getQuestionId().equals(currentQuestion.getQuestionId())){
//说明本题已经作答了---更新数据
TestService.studentAnswers.set(i, stuAnswer);
updateList = true; //更新了集合,即这道题之前写过,不再另外添加到list集合里
break; //已得到了结果,可直接跳出循环
}
}
if(!updateList){
//说明 遍历完整个 学生作答的list集合 也没有找到当前显示的题目---即这道题还没有做过,那么直接加入到list集合
TestService.studentAnswers.add(stuAnswer);
updateList = false; //恢复标志
}
}
}
private void showQuestion(int position) {
//拿到对应的题目
currentQuestion = TestService.questions.get(position);
//显示题目内容
tv_studenttest_number.setText(currentQuestion.getNumber());
tv_studenttest_questiontype.setText(currentQuestion.getType());
tv_studenttest_grade.setText("(分值:" + currentQuestion.getGrade() + ")");
tv_studenttest_question.setText(currentQuestion.getQuestion());
//清空选择--避免其余题目的选择的干扰
rg_studenttest_select.clearCheck();
cb_studenttest_A.setChecked(false);
cb_studenttest_B.setChecked(false);
cb_studenttest_C.setChecked(false);
if("单选题".equals(currentQuestion.getType())){
//则显示单选框--即多选框隐藏
rg_studenttest_select.setVisibility(View.VISIBLE);
ll_studenttest_cb.setVisibility(View.GONE);
rb_studenttest_C.setVisibility(View.VISIBLE); //防止前面有判断题
//显示选项内容
rb_studenttest_A.setText("A:" + currentQuestion.getAnswer_1());
rb_studenttest_B.setText("B:" + currentQuestion.getAnswer_2());
rb_studenttest_C.setText("C:" + currentQuestion.getAnswer_3());
}else if("多选题".equals(currentQuestion.getType())){
//则显示多选框--即隐藏单选框
rg_studenttest_select.setVisibility(View.GONE);
ll_studenttest_cb.setVisibility(View.VISIBLE);
//显示选项内容
cb_studenttest_A.setText("A:" + currentQuestion.getAnswer_1());
cb_studenttest_B.setText("B:" + currentQuestion.getAnswer_2());
cb_studenttest_C.setText("C:" + currentQuestion.getAnswer_3());
}else if("判断题".equals(currentQuestion.getType())){
//则显示单选框--即多选框隐藏
rg_studenttest_select.setVisibility(View.VISIBLE);
ll_studenttest_cb.setVisibility(View.GONE);
//且只显示两个选项
rb_studenttest_C.setVisibility(View.GONE);
//显示选项内容
rb_studenttest_A.setText("A:" + currentQuestion.getAnswer_1());
rb_studenttest_B.setText("B:" + currentQuestion.getAnswer_2());
}
//如果学生 选择了答案,再回过头来看时,要显示他选择的答案
//遍历学生 作答答案 的list集合,看是否 做过 当前显示的题目---因为学生 作答的list集合的数据的位置 并不是和 题目集合 一一对应的,可能他中间会先跳过某道题,所以要遍历查找
for (StudentAnswer studentAnswer : TestService.studentAnswers) {
if(studentAnswer.getQuestionId().equals(currentQuestion.getQuestionId())){
//说明本题已经作答了---显示作答的答案
if("多选题".equals(currentQuestion.getType())){
//切割答案
String[] stuAnswers = studentAnswer.getStudentAnswer().split(":");
for (int i = 0; i < stuAnswers.length; i++) {
if("A".equals(stuAnswers[i])){
cb_studenttest_A.setChecked(true);
}
if("B".equals(stuAnswers[i])){
cb_studenttest_B.setChecked(true);
}
if("C".equals(stuAnswers[i])){
cb_studenttest_C.setChecked(true);
}
}
}else{
//说明为 单选 或判断
if("A:".equals(studentAnswer.getStudentAnswer())){
rb_studenttest_A.setChecked(true);
}
if("B:".equals(studentAnswer.getStudentAnswer())){
rb_studenttest_B.setChecked(true);
}
if("C:".equals(studentAnswer.getStudentAnswer())){
rb_studenttest_C.setChecked(true);
}
}
break; //已经查找到了结果,不需要再循环了
}
}
//显示当前位置
int cp = position+1; //因为position是从0开始算的,所以+
tv_studenttest_currentposition.setText(cp+"");
//判断该题是否是最后一道题
if(position == TestService.questions.size()-1){
//说明是最后一道题---显示为 提交测试
btn_studenttest_next.setText("提交测试");
}else{
btn_studenttest_next.setText("下一题"); //当从最后一题往前翻时,也要变化 显示
}
}
private void showExamAlertDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(StudentTestActivity.this);
builder.setTitle("提示")
.setMessage("该测试类型为 考试。请注意:\n1.开始后将启动倒计时,请把握好考试时间。\n2.考试只有一次机会,中途退出将自动提交答卷,请保证手机电量充足,网络畅通。")
.setPositiveButton("开始考试", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
cd_studenttest_countdown.reStart();
}
}).setNegativeButton("不考了", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 直接返回上一个页面
setResult(Constants.CHANGE_TEST);
finish();
}
});
builder.show();
}
private void showloadingDialog(String message) {
dialog = new ProgressDialog(this);
dialog.setMessage(message);
dialog.setCanceledOnTouchOutside(false); //设置点击对话框之外的地方不会取消对话框
dialog.show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == Constants.CHANGE_TEST){
//从结果页面跳转回来,则自动返回至测试列表页面
setResult(Constants.CHANGE_TEST);
finish();
}
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK){
if("考试".equals(test.getType())){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("提示")
.setMessage("退出后将会自动交卷,确定退出吗。")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//交卷
showloadingDialog("正在交卷");
checkInTest();
}
}).setNegativeButton("取消", null);
builder.show();
}else{
//不是考试,则可以直接退出
finish();
}
return true;
}
return super.onKeyUp(keyCode, event);
}
}
最后
博客中可能有些地方描述的也不是很清楚,如果有问题,欢迎大家留言讨论。不足之处也欢迎大家指出。
转载请标明出处。谢谢支持!
作者:华 少