Android编程权威指南(第三版)挑战练习五

写在前面

欢迎所有人给我提出任何意见和建议
请注意每一次的demo都 没有 承接之前的挑战练习
如果有帮助的可以在下方评论
谢谢!


下载区
第五章挑战练习–>Link


目录

  • 挑战练习-题目-1
    • step 1. 新建一个常量(CheatActivity)
    • step 2. 加入函数onSaveInstanceState(CheatActivity)
    • step 3. 加入条件语句到onCreate中(CheatActivity)
    • 测试
  • 挑战练习-题目-2
    • step 1. 同样道理,先建一个常量作为标记(QuizActivity)
    • step 2. 将数据mIsCheater记录下来,以免旋转的时候没有了(QuizActivity)
    • step 3. 将数据重新取出来(QuizActivity)
    • 测试
  • 挑战练习-题目-3
    • step 1. 删除nextButtoon处的mIsCheater
    • step 2.新建
    • step 2.批量初始化mIscheater
    • step 3.mIscheater存与取的地方稍微改动
    • step 4.其他mIscheater地方,改为mIscheater[mCurrentIndex]
    • 最终结果


挑战练习-题目-1

  • 用户作弊后,可以 旋转 CheatActivity来清除作弊痕迹。

step 1. 新建一个常量(CheatActivity)

private static final String EXTRA_ANSWER_SHOWN =
        "com.bignerdranch.android.geoquiz.answer_shown";
/*新建下面这个常量*/       
private static final String QUESTION_SHOWN = "answer_shown";
/*新建变量cheatedFlag,默认flase即没有作弊*/ 
private boolean cheatedFlag = false;
private boolean mAnswerIsTrue;
private TextView mAnswerTextView;

解释:新建常量用于savebundle,变量只是一个标记,用于存储是否查看过答案

step 2. 加入函数onSaveInstanceState(CheatActivity)

...
public static boolean wasAnswerShown(Intent result) {
    return result.getBooleanExtra(EXTRA_ANSWER_SHOWN, false);
}
/* 加入此函数,放在onCreate之外,类之内就可以 */
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

    super.onSaveInstanceState(savedInstanceState);
    savedInstanceState.putBoolean(QUESTION_SHOWN, cheatedFlag);

}

解释:储存是否作弊的标志,以免在旋转之后被清除

step 3. 加入条件语句到onCreate中(CheatActivity)

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_cheat);
    /* 加入此条件语句,其他没有变化 */
    if (savedInstanceState != null) {
        cheatedFlag = savedInstanceState.getBoolean(QUESTION_SHOWN);
        setAnswerShownResult(cheatedFlag);
    }

    mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false);

    mAnswerTextView = (TextView)findViewById(R.id.answer_text_view);

    mShowAnswerButton = (Button)findViewById(R.id.show_answer_button);
    mShowAnswerButton.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            if(mAnswerIsTrue){
                mAnswerTextView.setText(R.string.true_button);
            }else{
    ...

解释:取出之前是否作弊的标志,并且设置到intent中,以便回传到QuizActivity

测试

点击cheat进入CheatActivity,点击showAnswer,旋转一下,点击返回,点击true或者false如果显示cheating is wrong 说明此方法有效,第一步完成
Android编程权威指南(第三版)挑战练习五_第1张图片
Android编程权威指南(第三版)挑战练习五_第2张图片

挑战练习-题目-2

  • 作弊返回后,用户可以旋转QuizActivity来清除mIsCheater变量值

step 1. 同样道理,先建一个常量作为标记(QuizActivity)

private static final String TAG = "QuizActivity";
private static final String KEY_INDEX = "index";
/* 新建一个常量用作标记 */
private static final String CHEATER_MARK = "IsCheater";
private static final int REQUEST_CODE_CHEAT = 0;

step 2. 将数据mIsCheater记录下来,以免旋转的时候没有了(QuizActivity)

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

    super.onSaveInstanceState(savedInstanceState);
    Log.i(TAG, "onSaveInstanceState");
    savedInstanceState.putInt(KEY_INDEX, mCurrentIndex);
    /* 把数据存起来 */
    savedInstanceState.putBoolean(CHEATER_MARK,mIsCheater);
}

step 3. 将数据重新取出来(QuizActivity)

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quiz);

    if (savedInstanceState != null) {
        mCurrentIndex = savedInstanceState.getInt(KEY_INDEX, 0);
        /* 取出mIsCheater */
        mIsCheater = savedInstanceState.getBoolean(CHEATER_MARK);
    }
    /* ........ */
}

测试

先点击cheat-showAnswer作弊一下,然后返回来QuizActivity,点击True/False,显示Cheating is wrong,接着旋转一下设备,再点击True/false,如果还是显示Cheating is wrong 的话说明第二题完成。
Android编程权威指南(第三版)挑战练习五_第3张图片(点击看大图)
Android编程权威指南(第三版)挑战练习五_第4张图片

挑战练习-题目-3

step 1. 删除nextButtoon处的mIsCheater

mNextButton = (Button) findViewById(R.id.next_button);
mNextButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mCurrentIndex = (mCurrentIndex + 1) % mQuestionBank.length;
        updateQuestion();
    }
});

step 2.新建

private TextView mQuestionTextView;
private static final String TAG = "QuizActivity";
private static final String KEY_INDEX = "index";
private static final String CHEATER_MARK = "IsCheater";
private static final int REQUEST_CODE_CHEAT = 0;
/* 新建一个常量表示问题总数 */ 
private static final int NUM_OF_Question = 6;
/* 将mIsCheater改为布尔值的数组 */
private boolean[] mIsCheater = new boolean[NUM_OF_QUESTION];
}

解释:

step 2.批量初始化mIscheater

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quiz);
    /* 初始化mIsCheater */
    for(int i = 0; i < NUM_OF_QUESTION;i++){
        mIsCheater[i] = false;
    }
    /* 下面省略 */
}

step 3.mIscheater存与取的地方稍微改动

/* 取数据 */
if (savedInstanceState != null) {
    mCurrentIndex = savedInstanceState.getInt(KEY_INDEX, 0);
        mIsCheater = savedInstanceState.getBooleanArray(CHEATER_MARK);
}
/* 存数据 */
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    Log.i(TAG, "onSaveInstanceState");
    savedInstanceState.putInt(KEY_INDEX, mCurrentIndex);
    /* 改为如下 */ 
    savedInstanceState.putBooleanArray(CHEATER_MARK, mIsCheater);
}

step 4.其他mIscheater地方,改为mIscheater[mCurrentIndex]

  @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != Activity.RESULT_OK) {
            return;
        }
        if (requestCode == REQUEST_CODE_CHEAT) {
            if (data == null) {
                return;
            }
            /* 返回QuizActivity数据的时候要改 */
            mIsCheater[mCurrentIndex] = CheatActivity.wasAnswerShown(data);

        }

    }
private void checkAnswer(boolean userPressedTrue) {
    boolean answerIsTrue = mQuestionBank[mCurrentIndex].isAnswerTrue();
    int messageResId = 0;
    /* checkAnswer检查答案的时候要改 */
    if(mIsCheater[mCurrentIndex]) {
        messageResId = R.string.judgment_toast;
    } else {
        if (userPressedTrue == answerIsTrue) {
            messageResId = R.string.correct_toast;
        } else {
            messageResId = R.string.incorrect_toast;
        }
    }
    Toast.makeText(this, messageResId, Toast.LENGTH_SHORT)
            .show();
}

最终结果

步骤是一样的,先作弊(点击cheat–>showAnswer),返回QuizActivity,然后按next直到回到原本作弊过的问题,再重新回答(True/False)显示Cheating is wrong
Android编程权威指南(第三版)挑战练习五_第5张图片(点击看大图)
总而言之,最后,无论用什么办法,你看过答案的题目,痕迹永远不会消失,系统永远记住你那一题作弊过


你可能感兴趣的:(Android,Studio)