Android权威编程练习(第二版)挑战练习5.5

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

分析:该作弊手段在CheatActivity上执行,因此在CheatActivity中记录作弊的痕迹即可(点击CHEAT按钮的动作

先定义一个记录作弊痕迹的布尔值

    private static final String EXTRA_ANSER_IS_TRUE = "com.example.geoquiz.answer_is_true";
    private static final String EXTRA_ANSWER_SHOWN = "com.example.geoquiz.answer_shown";
    private static final String CHEAT_INDEX="CheatIndex";

    private boolean cheatedFlag = false;//需添加的代码

    private boolean mAnswerIsTrue;
    private TextView mAnswerTextView;
    private Button mShowAnswer;

记录点击CHEAT按钮的动作

        @Override
        public void onClick(View v) {
                if (mAnswerIsTrue){
                    mAnswerTextView.setText(R.string.true_button);
                }else{
                    mAnswerTextView.setText(R.string.false_button);
                }

                cheatedFlag = true;//增加的代码

                setAnswerShownResult(cheatedFlag);//将参数换成cheatedFlag
            }

新增一个方法,覆盖onSaveInstanceState(Bundle)方法

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putBoolean(CHEAT_INDEX, cheatedFlag);
    }

重新对cheatedFlag赋值,并传入setAnswerShowResult函数,继而传到QuizActivity显示出来。

        if (savedInstanceState != null) {
            cheatedFlag = savedInstanceState.getBoolean(CHEAT_INDEX,false);
            setAnswerShownResult(cheatedFlag);
        }

OK。

 

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

分析:作弊的记录是在CheatActivity中通过Intent传到QuizActivity的。

而该旋转QuizActivity的操作在QuizActivity上进行,因此我们得将Intent传过来的值(是否作弊)记录下,方法和Q1一样。

先增加一个布尔变量作标志

    private static final String TAG = "QuizActivity";
    private static final String KEY_INDEX="index";

    private static final String CHEAT_SIGN="already_cheat";//增加的代码

    private static final int REQUEST_CODE_CHEAT=0;
    private boolean mIsCheater;

    private boolean cheatsign=false;//添加的代码

    private Button mTrueButton;
    private Button mFalseButton;

将作弊记录记录下来

    protected void onActivityResult(int requestCode,int resultCode,Intent data){
        if (resultCode!= Activity.RESULT_OK){
            return;
        }
        if(requestCode == REQUEST_CODE_CHEAT){
            if(data == null){
                return;
            }
            mIsCheater = CheatActivity.wasAnswerShown(data);

            cheatsign=mIsCheater;//增加的代码
        }
    }

覆盖onSaveInstanceState函数

    public void onSaveInstanceState(Bundle savedInstanceState){
        super.onSaveInstanceState(savedInstanceState);
        Log.i(TAG,"onSaveInstanceState");
        savedInstanceState.putInt(KEY_INDEX,mCurrentIndex);

        savedInstanceState.putBoolean(CHEAT_SIGN,cheatsign);//增加的代码
    }

重新把cheatsign取出来(放在CheckAnswer函数外面)

        if (savedInstanceState!=null){
            mCurrentIndex=savedInstanceState.getInt(KEY_INDEX,0);
            mIsCheater=savedInstanceState.getBoolean(CHEAT_SIGN,false);
        }

OK。

 

Q3:用户可以不断单击NEXT按钮,跳到偷看过答案的问题,从而使作弊记录丢失。

分析:

作弊原理是利用原本机制中的每到下一题,就自动将偷看标志mIsCheater值重新赋值为false的思路。

如今需要准确记录每一道题目是否已被偷看,因此为每一道题目都赋予一个是否被偷看过的标志。

我们可以把原本标志是否偷看的布尔值mIsCheater升级为一个存储布尔值的数组,加上mCurrentIndex记录了题目的序号,所以mIsCheater[mCurrentIndex]为相应题目是否被偷看的标志。

这样的话,在Q2中调用mIsCheater的地方都改为mIsCheater[mCurrentIndex]即可。

将mIsCheater修改为boolean数组

    private static final String TAG = "QuizActivity";
    private static final String KEY_INDEX="index";
    private static final String CHEAT_SIGN="already_cheat";
    private static final int REQUEST_CODE_CHEAT=0;
    private static final int QUESTIONS=5;//题目数量
    private boolean[] mIsCheater = new boolean[QUESTIONS];//将mIsCheater修改为boolean数组

开启应用时初始化数组,标志为false

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG,"onCreate(Bundle) called");
        setContentView(R.layout.activity_quiz);
        //初始化mIsCheater
        for (int i=0;i<5;i++){
            mIsCheater[i]=false;
        }

把点击下一题时的初始化操作删掉

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

覆盖onSaveInstanceState时也换成数组

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState){
        super.onSaveInstanceState(savedInstanceState);
        Log.i(TAG,"onSaveInstanceState");
        savedInstanceState.putInt(KEY_INDEX,mCurrentIndex);
        savedInstanceState.putBooleanArray(CHEAT_SIGN,mIsCheater);//换成数组
    }

取值时也一样

        if (savedInstanceState!=null){
            mCurrentIndex=savedInstanceState.getInt(KEY_INDEX,0);
            mIsCheater=savedInstanceState.getBooleanArray(CHEAT_SIGN);//修改为数组类
        }

接收来自CheatActivity的布尔值

    protected void onActivityResult(int requestCode,int resultCode,Intent data){
        if (resultCode!= Activity.RESULT_OK){
            return;
        }
        if(requestCode == REQUEST_CODE_CHEAT){
            if(data == null){
                return;
            }
            mIsCheater[mCurrentIndex] = CheatActivity.wasAnswerShown(data);
//            cheatsign=mIsCheater[mCurrentIndex];
        }
    }

引用偷看标志(mIsCheater[mCurrentIndex])

    private void checkAnswer(boolean userPressdTrue){
        boolean answerIsTrue = mQuestionBank[mCurrentIndex].isAnswerTrue();
        int messageResId = 0;
        if (mIsCheater[mCurrentIndex]){//修改的在这一行
            messageResId = R.string.judgment_toast;
        }else {
            if (userPressdTrue == answerIsTrue){
                messageResId = R.string.correct_toast;
            }else{
                messageResId = R.string.incorrect_toast;
            }
        }
        Toast.makeText(this,messageResId,Toast.LENGTH_SHORT).show();
    }

done。

你可能感兴趣的:(Android权威编程练习(第二版)挑战练习5.5)