四、简单刷题APP(题库是Excel)之单选和多选的跳转

好了,前面三篇文章,已经完成了题目的导入了,接下来要开始进入刷题模式了。

再回顾一下刷题要完成的功能:
刷题界面

  • 做对当前题,选项变绿并跳到下一题,做错选项变红并显示解析

  • 手动跳下一题,上一题

  • 查看答案,隐藏答案

在此说明,虽然功能是实现了,但是代码写的比较复杂,自己当初也是改了很久的,后面是想到另外一个办法了,但是自己又懒得改了。(主要是那时写完这段已经头昏脑胀了,自己都乱了)可能之后心情好了就会改了,哈哈哈。

好了,废话不多说,既然代码自己写的有点麻烦,还是先说思路吧。

  • 首先进行查询数据库,把数据库的数据全部查询出来,放在数组中(当然是为了之后操作方便些了)

  • 因为有单选和多选,所以要有两个layout,一个是单选,一个是多选的,来回切换。应该是还有别的办法的,那时网上找了很多解决单选多选的问题的,有说自己做选择框的,因为自己能力有限,所以用了笨办法实现它。我在activity中显示两个layout,当初可能代码改的有点乱了,没改对,于是笨办法就是首先显示的是单选的layout,多选的layout都是new出来的,代码有点多。(之后会努力改进的)

  • 布局解决后就把数据绑定到控件即可

###1.查询数据库

List<QuestionBean> xitiList;
xitiList = new ArrayList<QuestionBean>();
public void chaxun(){
		//把数据库的数据查询出来
        Cursor cursor = db.query("xiti", null, null, null, null, null, null, null);
        while (cursor.moveToNext()) {
        	//对应数据库表格的列,一一对应
			int _id = cursor.getInt(0);		     
			String title= cursor.getString(1);
			String optionA = cursor.getString(2);
			String optionB = cursor.getString(3);
			String optionC = cursor.getString(4);
			String optionD = cursor.getString(5);
			String answer = cursor.getString(6);
			String jiexi = cursor.getString(7);
		    QuestionBean q = new QuestionBean(_id, title, optionA, optionB, optionC, optionD, answer, jiexi);
		    xitiList.add(q);    //List<QuestionBean> xitiList; 数组
        }		
	}

###2.单选设置
####2.1单选布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
            <TextView
                android:id="@+id/tv_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="18sp"
                android:text="考题"
                 >
                <requestFocus />
            </TextView>
<!--  android:layout_marginTop="2dp" 控件间的距离 -->
         <RadioGroup
        android:id="@+id/rg_base"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dp" >

        <RadioButton
            android:id="@+id/rb_option_a"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="选项"
            android:textSize="15sp" />

        <RadioButton
            android:id="@+id/rb_option_b"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="选项"
            android:textSize="15sp" />

        <RadioButton
            android:id="@+id/rb_option_c"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="选项"
            android:textSize="15sp" />

        <RadioButton
            android:id="@+id/rb_option_d"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="选项"
            android:textSize="15sp" />
    </RadioGroup>
        <!-- android:text="答案" -->
        <TextView
             android:id="@+id/text_answer"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:textSize="15sp"
             />
        <!-- android:text="解析" -->
        <TextView
             android:id="@+id/text_jiexi"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             
             android:textSize="15sp"
             />

    </LinearLayout>
    

    <Button
        android:id="@+id/btn_previous"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:text="上一题"
         />
	<Button
        android:id="@+id/btn_look"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerInParent="true"
        android:text="查看答案"
         />
    <Button
        android:id="@+id/btn_next"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:text="下一题" 
        />
</RelativeLayout>

####2.2 单选数据绑定

if(question.getOptionC().equals("")){    //如果选择C为空,说明是判断题
						rb_option_c.setVisibility(View.GONE);//把C、D选项隐藏
						rb_option_d.setVisibility(View.GONE);
						//设置题目tv_title内容
						tv_title.setText((currentQuestionIndex + 1) + "." + question.getTitle()); 
						rb_option_a.setText(question.getOptionA()); //设置A选项的内容
						rb_option_b.setText(question.getOptionB()); //设置B选项的内容
					}
					else {
						tv_title.setText((currentQuestionIndex + 1) + "." + question.getTitle());
						rb_option_a.setText(question.getOptionA());
						rb_option_b.setText(question.getOptionB());
						rb_option_c.setText(question.getOptionC());
						rb_option_d.setText(question.getOptionD());
					}

###3.多选设置
不是在xml文件写的,控件都是new出来的,代码量挺多的

####3.1 先把控件new出来

private void initView2() {
			tv_title_t = new TextView(this);		//题目
			text_answer_t = new TextView(this);		//答案
			text_jiexi_t = new TextView(this);		//解析
			
			cb_option_a = new CheckBox(this);		//多选框A
			cb_option_b = new CheckBox(this);		//多选框B
			cb_option_c = new CheckBox(this);		//多选框C
			cb_option_d = new CheckBox(this);		//多选框D
			
			bt_tijiao = new Button(this);			//提交按钮			
			btn_previous_t = new Button(this);		//上一题按钮
			btn_look_t = new Button(this);			//查看答案按钮
			btn_next_t = new Button(this);			//下一题按钮
		}

####3.2 把控件有序的布局和绑定数据

private void dxbuju() {
			initView2();	//多选布局,控件都是new出来的
			//activity_shuati是空白的,因为有内容就会与单选的内容冲突覆盖了
			ViewGroup viewGroup = (ViewGroup) LayoutInflater.from(this).inflate(R.layout.activity_shuati, null); 
			viewGroup.addView(tv_title_t);	//在activity_shuati布局中添加题目tv_title_t控件
			//相对布局RelativeLayout.LayoutParams.WRAP_CONTENT为包裹内容,第一个参数是宽,第二个参数是高
			RelativeLayout.LayoutParams params_titile = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);					
			tv_title_t.setText((currentQuestionIndex + 1) + "." + question.getTitle());	//设置题目内容
			tv_title_t.setTextSize(18);		//设置字体大小
			tv_title_t.setTextColor(Color.BLACK);	//设置字体颜色
			tv_title_t.setId(1);					//设置控件的id
			tv_title_t.setLayoutParams(params_titile); //将设置的控件属性添加到布局中
			
			viewGroup.addView(cb_option_a);				//在activity_shuati布局中添加多选Acb_option_a控件
			cb_option_a.setText(question.getOptionA());	//设置选项A的内容
			cb_option_a.setTextSize(15);			
			RelativeLayout.LayoutParams params_a = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
			params_a.addRule(RelativeLayout.BELOW, 1);	//cb_option_a控件位于id为1的控件下
			cb_option_a.setLayoutParams(params_a);
			cb_option_a.setId(2);
			//...
			//此处省略了其他的控件的设置,与上类似
			setContentView(viewGroup); //显示布局
			
		}

因为其他控件设置都类似,在此就不一一注释了。


###4.实现上一题时记录下自己选过的题目,思路如下:

  • 将选过的答案存入数组中

定义的数组如下:

//0b00000001-A 0b00000010-B 0b00000100-C 0b00001000-C 
		//select A: answerList.add(new Integer(1))
		//select B: answerList.add(new Integer(2))
		//select C: answerList.add(new Integer(4))
		//select D: answerList.add(new Integer(8))
		//select A,C,D: answerList.add(new Integer(13))
	List<Integer> answerList = new ArrayList<Integer>();

下面实现每一种情况,数组中存入的数据

####4.1 单选

private void fanhui() {
			//判断记录所选答案数组的数据
			switch (answerList.get(currentQuestionIndex)) {
			case 1://只选了A选项
				panduan_a(); //判断所选的是否正确
				break;
			case 2:
				panduan_b();
				break;
			case 4:
				panduan_c();
				break;
			case 16:
				panduan_d();
				break;
			case 3://选过A、B选项
				panduan_a();
				panduan_b();
				break;
				//...
			//这里省略了其他情况
			default:
				break;
			}
		}

上面代码中出现的panduan_a()功能是判断正确答案与所选的是否一致,如果正确选项内容显示绿色,否则显示红色,在此只贴了其中一个,其他的类似。

private void panduan_a() {
			if (!question.getAnswer().equals("A")) {
				rb_option_a.setTextColor(Color.RED);
			}else{
				rb_option_a.setTextColor(Color.GREEN);
			}	
		}

####4.2 多选
其实多选的与单选的类似

private void Dfanhui() {
			switch (answerList.get(currentQuestionIndex)) {
			case 1: //将选过的选项选中
				cb_option_a.setChecked(true);
				break;
			case 2:
				cb_option_b.setChecked(true);
				break;
			case 4:
				cb_option_c.setChecked(true);
				break;
			case 16:
				cb_option_d.setChecked(true);
				break;
				
			case 3:
				cb_option_a.setChecked(true);
				cb_option_b.setChecked(true);
				break;
			//...
			//这里省略了其他选过的情况
			default:
				break;
			}
		}

这里的判断与单选有所不同,因为多选在都选对时,要点击提交才去判断对错,不要担心会自动跳到下一题了,在重新设置为选中状态时,再判断所选的与答案是否一致,错误的选项变红,正确的变绿色

private void pundun() {
			boolean A = question.getAnswer().contains("A");
			boolean B = question.getAnswer().contains("B");
			boolean C = question.getAnswer().contains("C");
			boolean D = question.getAnswer().contains("D");
			if(A){
				if(cb_option_a.isChecked()){
					cb_option_a.setTextColor(Color.GREEN);
				}
			}
			else{
				if(cb_option_a.isChecked()){
					cb_option_a.setTextColor(Color.RED);
				}
			}
			if(B){
				if(cb_option_b.isChecked()){
					cb_option_b.setTextColor(Color.GREEN);
				}
			}
			else{
				if(cb_option_b.isChecked()){
					cb_option_b.setTextColor(Color.RED);
				}
			}
			if(C){
				if(cb_option_c.isChecked()){
					cb_option_c.setTextColor(Color.GREEN);
				}
			}
			else{
				if(cb_option_c.isChecked()){
						cb_option_c.setTextColor(Color.RED);
					}
			}
			if(D){
				if(cb_option_d.isChecked()){
					cb_option_d.setTextColor(Color.GREEN);
				}
			}
			else{
					if(cb_option_d.isChecked()){
						cb_option_d.setTextColor(Color.RED);
					}
			}
			
		}

###5.题目跳转以及判断的问题

@Override
		public void onCheckedChanged(RadioGroup group, int checkedId) {
			RadioButton rb_option = (RadioButton) findViewById(checkedId);
			//如果选项中没有选中,就不用进行判断了,因为在做对一题后会自动跳转到下一题,
			//要把之前选的取消选中状态,就会触发这个方法的调用,就导致可能会再跳到下一题了
			if(!rb_option.isChecked()){
				return;
			}
			//判读选中状态,在答案的数组上写入答案的状态
			if (checkedId == rb_option_a.getId()) {
				option = "A";
				daan = daan + 1;
			} else if (checkedId == rb_option_b.getId()) {
				option = "B";
				daan = daan + 2;
			} else if (checkedId == rb_option_c.getId()) {
				option = "C";
				daan = daan + 4;
			} else if (checkedId == rb_option_d.getId()) {
				option = "D";
				daan = daan + 16;
			}
			//下标是题目号 一一对应
			//第一个参数是下标,第二个参数是答案的状态
			answerList.set(currentQuestionIndex, daan); 
			System.out.println(answerList + "");
			System.out.println(answerList.get(currentQuestionIndex) + "");
			//做错时选项内容变化,并显示解析
			if (!option.equals(question.getAnswer())) {
				rb_option.setTextColor(Color.RED);
				text_jiexi.setText("解析:"+ question.getjiexi());
			}
			//做对时内容颜色变绿,并延时一段时间
			else{
				rb_option.setTextColor(Color.GREEN);
				mHandler .postDelayed(new Runnable() {
					
					@Override
					public void run() {
						 mHandler.sendEmptyMessage(1);
					}
				}, 500); 
			}
				
		}

注意private int currentQuestionIndex = 0;是题号数
这里附上

 private Handler mHandler = null;
 mHandler = new Handler() {
		     @Override
		     public void handleMessage(Message msg) {
		         super.handleMessage(msg);
		           //半s后执行代码
		         if(!question.getAnswer().equals("A")&&!question.getAnswer().equals("B")&&!question.getAnswer().equals("C")&&!question.getAnswer().equals("D")){	
		        	 Dnext();
		         }else {
					next();
				}
		        
		         
		     }
		};

###6.最后附上绑定数据,具体的调用

private void setData() {
			question = xitiList.get(currentQuestionIndex);
			answerList.add(0);
			daan = 0;
				System.out.println(answerList+ "");
				if(!question.getAnswer().equals("A")&&!question.getAnswer().equals("B")&&!question.getAnswer().equals("C")&&!question.getAnswer().equals("D")){	
					dxbuju();					
					anniu();
					Dfanhui();//多选的返回时判断用户的选择
					pundun();
				}else{
					setContentView(R.layout.activity_strat);
					initView();
					fanhui();
					if(question.getOptionC().equals("")){    //如果选择C为空,说明是判断题
						rb_option_c.setVisibility(View.GONE);//把C、D选项隐藏
						rb_option_d.setVisibility(View.GONE);
						//设置题目tv_title内容
						tv_title.setText((currentQuestionIndex + 1) + "." + question.getTitle()); 
						rb_option_a.setText(question.getOptionA()); //设置A选项的内容
						rb_option_b.setText(question.getOptionB()); //设置B选项的内容
					}
					else {
						tv_title.setText((currentQuestionIndex + 1) + "." + question.getTitle());
						rb_option_a.setText(question.getOptionA());
						rb_option_b.setText(question.getOptionB());
						rb_option_c.setText(question.getOptionC());
						rb_option_d.setText(question.getOptionD());
					}
					
					// 给RadioButton设置监听
					rg_base.setOnCheckedChangeListener(this);
				}
		}

上面我认为是难点,也是我做项目比较难搞定的部分,下面这些是简单的功能,这里只填了单选的,多选思路也是类似的,就不在此啰嗦了哈。
###7. 上一题

private void previous(){
		if (currentQuestionIndex > 0) {
			currentQuestionIndex--;
			// 将选项被选中的状态清空					
			rb_option_a.setChecked(false);
			rb_option_b.setChecked(false);
			rb_option_c.setChecked(false);
			rb_option_d.setChecked(false);
			answerList.get(currentQuestionIndex);
			text_answer.setText(" ");
			text_jiexi.setText(" ");
			setData();
		} else {
			Toast.makeText(StartActivity.this, "已经到头啦!", Toast.LENGTH_SHORT)
					.show();
		}
	}

###8.下一题

private void next(){
			if (currentQuestionIndex < sizeOfList - 1) {
				currentQuestionIndex++;
				// 将选项被选中的状态清空
				rb_option_a.setChecked(false);
				rb_option_b.setChecked(false);
				rb_option_c.setChecked(false);
				rb_option_d.setChecked(false);
				text_answer.setText(" ");
				text_jiexi.setText(" ");
				setData();
			} else {
				Toast.makeText(StartActivity.this, "这已经是最后一题啦!",
						Toast.LENGTH_SHORT).show();
			}
		}

###9.查看答案

if(btn_look.getText().equals("查看答案")){
					text_answer.setText("答案:" + question.getAnswer());
					btn_look.setText("隐藏答案");
				}else{
					text_answer.setText("");
					btn_look.setText("查看答案");
				}

到此为止,这个项目的难点已经总结完毕了,如有不妥之处,欢迎指教。
一、简单刷题APP(题库是Excel)之项目功能和效果图
二、简单刷题APP(题库是Excel)之实现文件管理器添加题库
三、简单刷题APP(题库是Excel)之在APP添加题目

欢迎加群学习交流
在这里插入图片描述

  • 12
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
刷题App的数据设计是一个关键的部分,它需要考虑到用户数据、题目数据、答题记录以及统计分析等方面。 首先,用户数据是刷题App的核心,所以需要设计一个用户表来存储用户的基本信息,包括用户名、密码、个人信息等。通过用户表,可以实现用户的注册、登录、个人设置等功能。 其次,题目数据是刷题App的基础,所以需要设计一个题目表来存储题目的相关信息,包括题目类型、题目内容、选项、答案等。通过题目表,可以实现题目的查看、搜索、添加、删除、修改等功能。 另外,为了方便用户记录答题情况,需要设计一个答题记录表,用于存储用户的答题记录信息,包括用户ID、题目ID、答案、得分等。通过答题记录表,可以实现用户答题历史的查看、统计、分析等功能。 此外,为了提供更好的用户体验,可以设计一个错题本表,用于存储用户答错的题目信息。通过错题本表,用户可以方便地查看和复习自己答错的题目,提升学习效果。 最后,为了提供更深入的数据分析和统计功能,可以设计统计表来记录用户的答题情况,包括用户答题总数、正确率、平均得分等指标,以便进行数据分析和用户画像。 总之,刷题App的数据设计需要考虑到用户数据、题目数据、答题记录和统计分析等方面,通过合理的表结构和功能设计,可以实现用户的注册、登录、个人设置、题目查看、答题记录、错题本、统计分析等功能,提供一个高效、便捷、个性化的刷题学习平台。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值