目录
代码实现了任意在arrays文件中添加题目,不需要修改java代码即可完成答题。
此笔记为2022年下半年外包班某某课作业笔记,如有相同作业同学应该为同一老师,大家谨慎借鉴
作业要求
实现用户在线答题的功能,要求如下,运行效果如下图所示:
1. 全部为多项选择题;
2. 每个题目由1个题面和多个选项组成,选项个数不固定,最多6个;题目的数量根据XML文件内容解析(以后可以扩充XML,不需要修改程序),不要只固定为3个。
3. 用户点击开始按键后,开始答题和计时;
4. 答题时,用户做出选择后,点击提交,跳转到下一题;全部答完后,使用Toast提示框提示用户的答对、答错的个数和总共耗时。
5. 在界面上方显示当前已答个数和待答个数。
6. 题面、选项和答案,作为XML资源保存,如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="testTitle">
<item>android开发长度单位有</item>
<item>在手机开发中,常用的数据库是哪一个?</item>
<item>下列哪些属性是android布局可用的?</item>
<item>自加</item>
</string-array>
<string-array name="testOption1">
<item>dp</item>
<item>dip</item>
<item>px</item>
<item>sp</item>
</string-array>
<string-array name="testOption2">
<item>Oracle</item>
<item>DB2</item>
<item>Mysql</item>
<item>SQLite</item>
<item>MongoDB</item>
</string-array>
<string-array name="testOption3">
<item>layout_toRightOf</item>
<item>stretchColumns</item>
<item>layout_width</item>
<item>orientation</item>
<item>hint</item>
</string-array>
<string-array name="testOption4">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
</string-array>
<array name="testOptionAll">
<item>@array/testOption1</item>
<item>@array/testOption2</item>
<item>@array/testOption3</item>
<item>@array/testOption4</item>
</array>
<string-array name="anwser">
<item>1,2,3,4</item>
<item>4</item>
<item>1,2,3,4,5</item>
<item>1,2,6</item>
</string-array>
</resources>
本题用到的知识点补充
1、设置复选框的隐藏与显示
CheckBox.setVisibility(visible)//设置显示
CheckBox.setVisibility(CheckBox.GONE);//设置隐藏
2、取消复选框的选择(如果不设置,在跳转下一题后复选框会已经被选中)
CheckBox.setChecked(false);
3、取当前时间
startTime = System.currentTimeMillis();//单位为毫秒
startTimeSeconds = start / 1000; //单位为毫秒,转换为秒
结束是时间再取一次,然后相减
解题思路
1、在layout.xml文件中设置好布局
2、在Activity文件中设置显示指定的页面
3、声明各个需要用到的组件
4、开始主要代码
5、在按钮显示为开始的时候把复选框清除显示(写在了方法中)
6、提前获取数组文件中的内容。题目数组,选项集合数组。
7、提前定义好控制次数的变量。注意我这里获取答案的变量j初始值定义为-1,因为要控制获取答案和选择后的答案对比
8、点击按钮
8.1开始计时,只在第一次点击开始时计时
8.2当点击次数小于题目数量时进入if内部,将按钮文字设置为提交
8.3获取题目,显示题目个数提示到文本框里
8.4获取选项集合
int a = optionAll_arr.getResourceId(i[0],0); //获取i【0】个选项集合
String[] option_arr = getResources().getStringArray(a); //各个选项存入option_arr
8.5将选项放入复选框内部,在这里写入了方法内
8.6调用方法,判断答案,同时在方法内获取选择的内容
8.7最后题目数量减一,i++,j++
注意每次点击后把复选框取消选中
9、当点击次数等于题目数时
9.1获取结束时间,
9.2最后判断答案
9.3用Toast弹出用时和答对题目个数
9.4重新将题目框,数量提示框,按钮文本设为初始状态。
完整代码
MainActivity.java代码
import androidx.appcompat.app.AppCompatActivity;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Arrays;
public class MainActivity5 extends AppCompatActivity {
private CheckBox cb1,cb2,cb3,cb4,cb5,cb6; //声明复选框
int count = 0;//记录答对题的个数
long start, startSeconds, end, endSeconds; //开始时间,开始时间(秒),结束时间,结束时间(秒)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
get_checkbox();//调用方法,初始化6个复选框
//启动时按钮显示开始,此时不显示复选框
delete_content(); //先调用方法清除复选框显示。
TextView Tips = findViewById(R.id.tishi); //顶部提示题目个数文本框
TextView title = findViewById(R.id.timu); //题目显示条
//题目
String[] title_arr = getResources().getStringArray(R.array.testTitle); //访问字符型数组,获取题目
//题的选项内容
TypedArray optionAll_arr = getResources().obtainTypedArray(R.array.testOptionAll); //访问普通类型数组,获取所有题目选项
final int[] title_count = {optionAll_arr.length()}; //未做题目数(所有题目数量),等于所有选项组的数量
final int[] i = {0}; //循环变量,控制第几次点击按钮
final int[] j = {-1};//控制获取答案的变量,因为答案可以直接获取,而选择的选项内容要点击后才能获取,所以要初始值为-1使其相对慢一次
Button button1 = findViewById(R.id.button1);//唯一一个按钮,后面设置按钮text文本的变化。
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (i[0] == 0) { //if内部获取开始时间,仅当i【0】=0是设置开始
start = System.currentTimeMillis(); //点击按钮,设置开始时间,并且只能第一次进入按钮时设置
startSeconds = start / 1000; //单位为毫秒,转换为秒
}
//i【0】的值要小于题目的数量,初始为0.后期每次++1
if (i[0] < optionAll_arr.length()){
button1.setText("提交");//进入做题环节,改变按钮文字为提交
String test_title = title_arr[i[0]]; //从获取的题目数组中显示第i【0】个
Tips.setText("您当前已答"+i[0]+"还剩"+ title_count[0] +"题");
title.setText(test_title); //将题目显示在textView中
int a = optionAll_arr.getResourceId(i[0],0); //获取i【0】个选项集合
String[] option_arr = getResources().getStringArray(a); //各个选项存入option_arr
get_checkbox();//调用方法,初始化6个复选框
set_content(option_arr.length, option_arr); //调用方法(传入数组选项个数和内容),把选项内容放入到复选框
if(j[0] >=0){//判断答案的对错
judge_answer(j[0]);
}
title_count[0]--; //题目减一
i[0]++;
j[0]++;
}else {
end = System.currentTimeMillis(); //结束时间
endSeconds = end / 1000; //单位为毫秒,转换为秒
long time = endSeconds - startSeconds;
judge_answer(j[0]); //最后再判断一次答案
Toast.makeText(getApplicationContext(),"您答对"+count+"个题,耗时"+time+"秒",Toast.LENGTH_SHORT).show();
button1.setText("开始");
Tips.setText("");
title.setText("");
delete_content();//调用方法,清除复选框显示
title_count[0] = optionAll_arr.length();
count=0;//答对题目数归零
i[0] = 0; //重新让i[0]=0
j[0] = -1;
}
cancel_check(); //调用方法,取消复选框的选中
}
});
}
//找到6个复选框,初始化复选框
public void get_checkbox(){
cb1 = findViewById(R.id.cb1);
cb2 = findViewById(R.id.cb2);
cb3 = findViewById(R.id.cb3);
cb4 = findViewById(R.id.cb4);
cb5 = findViewById(R.id.cb5);
cb6 = findViewById(R.id.cb6);
}
//设置复选框的选项内容,a为长度,b为内容
//题目选项最少为4个
public void set_content(int a, String[] b){
int visible = 0;
//设置复选框的隐藏与显示
if (a==4){
cb1.setVisibility(visible);
cb2.setVisibility(visible);
cb3.setVisibility(visible);
cb4.setVisibility(visible);
}
if (a==5){
cb5.setVisibility(visible);
cb1.setVisibility(visible);
cb2.setVisibility(visible);
cb3.setVisibility(visible);
cb4.setVisibility(visible);
}else if (a==6){
cb5.setVisibility(visible);
cb6.setVisibility(visible); //设置显示复选框
cb1.setVisibility(visible);
cb2.setVisibility(visible);
cb3.setVisibility(visible);
cb4.setVisibility(visible);
}else {
cb5.setVisibility(cb5.GONE);
cb6.setVisibility(cb6.GONE); //设置隐藏
}
//while+switch语句显示选项内容
while (a>0){
switch (a) {
case 6:
cb6.setText(b[5]);
// cb6.setVisibility(visible); //设置显示复选框
a--;
case 5:
cb5.setText(b[4]);
cb5.setVisibility(visible);
a--;
case 4:
cb4.setText(b[3]);
a--;
case 3:
cb3.setText(b[2]);
a--;
case 2:
cb2.setText(b[1]);
a--;
case 1:
cb1.setText(b[0]);
a--;
}
}
}
//判断是否正确,a为索引(慢一次)
public void judge_answer(int a){
String select = "";//定义一个字符串,之后把选择的内容存进去
if (cb1.isChecked()&&select==""){select=select+"1";}else if (cb1.isChecked()&&select!=""){select=select+",1";}
if (cb2.isChecked()&&select==""){select=select+"2";}else if (cb2.isChecked()&&select!=""){select=select+",2";}
if (cb3.isChecked()&&select==""){select=select+"3";}else if (cb3.isChecked()&&select!=""){select=select+",3";}
if (cb4.isChecked()&&select==""){select=select+"4";}else if (cb4.isChecked()&&select!=""){select=select+",4";}
if (cb5.isChecked()&&select==""){select=select+"5";}else if (cb5.isChecked()&&select!=""){select=select+",5";}
if (cb6.isChecked()&&select==""){select=select+"6";}else if (cb6.isChecked()&&select!=""){select=select+",6";}
String select_arr[] = select.split("\\s"); //把自己选择的答案字符串转为数组
//获取设定好的答案
String[] answer_arr = getResources().getStringArray(R.array.anwser);//从数组中获取答案
String answer = answer_arr[a];//读取第a个答案,为字符串
String answer_arr1[] = answer.split("//,");//以,为分割点依次向不同的数组下标里存放数据,逗号不会被存到数组里,0存到arr[0],12存到arr[1],3存到arr[2]
// String zhuan_huan_arr[] = arr.split("");//将字符串中所有字符都存到数组里,0,12,3代表一个元素,存到arr[0]中
if (Arrays.equals(select_arr,answer_arr1)){
count++;
}
}
//取消复选框选中方法
public void cancel_check(){
cb1.setChecked(false);
cb2.setChecked(false);
cb3.setChecked(false);
cb4.setChecked(false);
cb5.setChecked(false);
cb6.setChecked(false);
}
//设置一个循环过后清除复选框显示
public void delete_content(){
cb1.setVisibility(cb1.GONE);
cb2.setVisibility(cb2.GONE);
cb3.setVisibility(cb3.GONE);
cb4.setVisibility(cb4.GONE);
cb5.setVisibility(cb5.GONE);
cb6.setVisibility(cb6.GONE);
}
}
arrays.xml代码
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="testTitle">
<item>android开发长度单位有</item>
<item>在手机开发中,常用的数据库是哪一个?</item>
<item>下列哪些属性是android布局可用的?</item>
<item>自加</item>
</string-array>
<string-array name="testOption1">
<item>dp</item>
<item>dip</item>
<item>px</item>
<item>sp</item>
</string-array>
<string-array name="testOption2">
<item>Oracle</item>
<item>DB2</item>
<item>Mysql</item>
<item>SQLite</item>
<item>MongoDB</item>
</string-array>
<string-array name="testOption3">
<item>layout_toRightOf</item>
<item>stretchColumns</item>
<item>layout_width</item>
<item>orientation</item>
<item>hint</item>
</string-array>
<string-array name="testOption4">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
</string-array>
<array name="testOptionAll">
<item>@array/testOption1</item>
<item>@array/testOption2</item>
<item>@array/testOption3</item>
<item>@array/testOption4</item>
</array>
<string-array name="anwser">
<item>1,2,3,4</item>
<item>4</item>
<item>1,2,3,4,5</item>
<item>1,2,6</item>
</string-array>
</resources>
activity_main.xml页面布局代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/tishi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#60FFEB3B"
/>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始"
/>
<TextView
android:id="@+id/timu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#4EFFEB3B"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/LinearLayout_cb"
android:orientation="vertical">
<CheckBox
android:id="@+id/cb1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<CheckBox
android:id="@+id/cb2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<CheckBox
android:id="@+id/cb3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<CheckBox
android:id="@+id/cb4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<CheckBox
android:id="@+id/cb5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<CheckBox
android:id="@+id/cb6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>
运行效果展示
Android答题
以上代码还可以精简优化:
1、比如在声明CheckBox时,把6个CheckBox存放到数组中就可以用循环来获取,大概还可以少些20行吧,
2、在judge_answer()判断选项与答案的对错时可以不用这么麻烦的每次判断是否为空然后选择在前还是在后面加逗号(,)可以使用select=select+" 1",注意1前面有一个空格,虽然这样会导致最后的数组前面有多余的空格,但是在转为数组之前可以空trim()方法把字符串前后的空格都删掉
以上优化大家可以自行操作,欢迎提出问题。
初学编程,代码逻辑可能有些乱,有些地方不合规范欢迎指出,大家一起进步!
学长做过类似的单选答题程序链接在这实现用户在线答题的功能,要求如下,运行效果如下图所示: 1. 全部为单项选择题;