写在前面:
欢迎所有人给我提出任何意见和建议
请注意每一次的demo都没有承接之前的挑战练习
如果有帮助的可以在下方评论写几个字
谢谢!
下载区:
挑战练习三 完整代码 ->Link
没有积分可以私聊或者评论我,我会提供Github地址供你下载学习使用
挑战练习-题目-1: 禁止一题多答
用户答完某道题,就禁掉那道题对应的按钮,防止用户一题多答。
参考解决办法:
step 1:加入数据,与get、set方法(Question.java)
private boolean mAnswered;
public Question(int textResId, boolean answerTrue) {
...
}
public boolean isAnswered() {
return mAnswered;
}
public void setAnswered(boolean answered) {
mAnswered = answered;
}
解释:加入了mAnswered属性,用来标记是否完成回答。
step 2:设置函数,在QuizActivity类内,checkAnswer()后。(QuizActivity)
//封装一个检查是否回答过问题的函数,以便调用
private void checkIfAnswered(){
boolean answerIsAnswered = mQuestionBank[mCurrentIndex].isAnswered();
if (answerIsAnswered == true) {
//如果题目被回答,则按键设置不可按下
mTrueButton.setEnabled(false);
mFalseButton.setEnabled(false);
} else {
//如果题目没有被回答,则按键设置可按下
mTrueButton.setEnabled(true);
mFalseButton.setEnabled(true);
}
}
解释:回到主Acitivity,实现检测按钮是否按下的函数,以便调用。
step 3:在下面两个地方调用checkIfAnswered(),并加入mQuestionBank.......(QuizActivity.java)
private void updateQuestion() {
...
mQuestionTextView.setText(question);
checkIfAnswered();
}
private void checkAnswer(boolean userPressedTrue) {
... else {
messageResId = R.string.incorrect_toast;
}
mQuestionBank[mCurrentIndex].setAnswered(true);
checkIfAnswered();
Toast.makeText(this, messageResId, Toast.LENGTH_SHORT)
.show();
}
解释:在每一次页面刷新时&点击true或false按钮之后,调用刚刚写的CheckIfAnswered函数,刷新两个按钮的状态。
加上一句mQuestionBank[mCurrentIndex].setAnswered(true)是设置刚刚新增的属性,即记录下问题是否被回答。
step 4:存储数据(QuizActivity.java)
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Log.i(TAG, "onSaveInstanceState");
savedInstanceState.putInt(KEY_INDEX, mCurrentIndex);
boolean answerIsAnswered[] = new boolean[mQuestionBank.length];
for(int i = 0; i < mQuestionBank.length;i++)
{
answerIsAnswered[i] = mQuestionBank[i].isAnswered();
}
savedInstanceState.putBooleanArray(KEY_ANSWERED, answerIsAnswered);
}
解释:将是否回答的数据存入数组,然后放到Bundle中。KEY_ANSWERED此时可能有红色波浪线,完成下一步,加入KEY_ANSWERED即可。
step 5 : 取出数据
private static final String KEY_INDEX = "index";
private static final String KEY_ANSWERED = "answered";
...
if (savedInstanceState != null) {
mCurrentIndex = savedInstanceState.getInt(KEY_INDEX, 0);
boolean answerIsAnswered[] = savedInstanceState.getBooleanArray(KEY_ANSWERED);
for(int i = 0; i < mQuestionBank.length;i++)
{
mQuestionBank[i].setAnswered(answerIsAnswered[i]) ;
}
}
解释:加上标志KEY_ANSWERED,保存所有Answered状态,
至此,完成了第一道题目。
相关资料:
函数:void putBooleanArray(String key, boolean[] value)
解释:Inserts a boolean array value into the mapping of this Bundle, replacing any existing value for the given key.
挑战练习-题目-2:评分
用户答完全部题后,显示一个toast消息,给出百分比形式的评分。
参考解决办法:(基于上一题的参考答案,不然会出bug)
step 1:QuizActivity.java数据域加入全局变量(QuizActivity.java)
private int userAnsweredCorrect = 0;
...
private static final String KEY_CORRECT = "correct";
解释:设置变量userAnswerCorrect记录答对的题目数量。用 公式“答对的题 / 全部题目 = 答对率” 即可计算评分
step 2:记录答对次数
private void checkAnswer(boolean userPressedTrue) {
boolean answerIsTrue = mQuestionBank[mCurrentIndex].isAnswerTrue();
int messageResId = 0;
if (userPressedTrue == answerIsTrue) {
messageResId = R.string.correct_toast;
//如果答对则记录答对次数
userAnsweredCorrect++;
} else {
messageResId = R.string.incorrect_toast;
}
mQuestionBank[mCurrentIndex].setAnswered(true);
checkIfAnswered();
Toast.makeText(this, messageResId, Toast.LENGTH_SHORT)
.show();
}
step 3:增加显示百分比函数(QuizActivity.java)
private void showRecored(){
boolean allAnsnswered = true;
String message = null;
double correctMark = 0;//百分比形式的评分,正确率
int correctAnswerNum = 0;//答对的题目数量
for(int i = 0; i < mQuestionBank.length; i++){
if(mQuestionBank[i].isAnswered() == false) {
allAnsnswered = false;
break;
}
}
if(allAnsnswered == true){
correctMark = (double)userAnsweredCorrect/mQuestionBank.length;
//保留后两位
correctMark = (double)((int)(correctMark * 10000)/100.0);
message = "正确率" + String.valueOf(correctMark) + "%";
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
}
解释:allAnswered表示是否全部答对,for循环用于检索是否还有没有回答的题目,如果都回答了,allAnswered为true,计算答对率并输出。
step 4:三个按钮的回调函数里调用(QuizActivity.java)
mTrueButton = (Button) findViewById(R.id.true_button);
mTrueButton.setOnClickListener(new View.OnClickListener() {
...
showRecored();
}
});
mFalseButton = (Button) findViewById(R.id.false_button);
mFalseButton.setOnClickListener(new View.OnClickListener() {
...
showRecored();
}
});
mNextButton = (Button) findViewById(R.id.next_button);
mNextButton.setOnClickListener(new View.OnClickListener() {
...
showRecored();
}
});
解释:目的是要在按下按钮时,检查是否答完全部题目,如果回答完了,输出评分。所以三个按钮的回调函数里面都有放置显示函数。
step 5:同理,保存数据KEY_CORRECT(QuizActivity.java)
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
...
savedInstanceState.putInt(KEY_CORRECT, userAnsweredCorrect);
}
解释:同上,保存userAnsweredCorrect即答对的题目数量,到bundle中。
step 6:取出数据(QuizActivity.java)
@Override
protected void onCreate(Bundle savedInstanceState) {
...
userAnsweredCorrect = savedInstanceState.getInt(KEY_CORRECT);
}
解释:取出数据
至此,完成第三章的挑战练习