Quiz项目java代码部分

来源:互联网 发布:sfp端口是什么 编辑:程序博客网 时间:2024/05/16 17:39

QuizActivity
layout:显示题目的TextView(有响应事件,点击会自动下一题),对错两个Button,上下题两个Button,看答案一个Button
AnswerActivity
layout:警告语TextView,看答案Button,显示答案TextView
将用户是否看了答案返回给QuizActivity,以判断用户是否作弊
Question.class
int型题目id(要获取strings.xml里的资源),boolean型答案,boolean型答案是否被偷看过(为了避免用户看过答案后不断点击next重新返回该题,将是否看了答案与题目绑定,因为之前未绑定时只有一个isCheat,next时要将isCheat重置为否)

public class Question {    private int mQuestionId;    private boolean mIsAnwserTure;    private boolean mIsAnwserShown;    //要注意构造函数是没有返回值的不用写void    public  Question(int mQuestionId,boolean mIsAnwserTure)    {        this.mQuestionId=mQuestionId;        this.mIsAnwserTure=mIsAnwserTure;        //每新建一个question时把是否偷看初始化为否        this.mIsAnwserShown=false;    }    public boolean isAnwserShown() {        return mIsAnwserShown;    }    public void setAnwserShown(boolean anwserShown) {        mIsAnwserShown = anwserShown;    }    public boolean isAnwserTure() {        return mIsAnwserTure;    }    public void setAnwserTure(boolean anwserTure) {        mIsAnwserTure = anwserTure;    }    public int getQuestionId() {        return mQuestionId;    }    public void setQuestionId(int questionId) {        mQuestionId = questionId;    }}

公有方法可通过在构造方右键,generate-getter and setter来自动生成

public class QuizActivity extends AppCompatActivity {    private static final String TAG = "QuizActivity";    private static final String KEY_INDEX="index";    //private static final String IS_ANSWER_SHOWN="isAnswerShownIndex";    private static final int REQUEST_CODE_ANSWER=0;    private Button mTrueButton;    private Button mFalseButton;    private ImageButton mNextButton;    private ImageButton mPreButton;    private Button mSeeAnswer;    private TextView mTextView;    private int mCurrentId;    private Question[] questions=new Question[]            {                    new Question(R.string.quiz1,true),                    new Question(R.string.quiz2,true),                    new Question(R.string.quiz3,false)            };    //为了避免写两遍改变题目的代码将它单独写成一个私有方法    private void updateQuestion(int currentId)    {        mTextView.setText(questions[currentId].getQuestionId());    }    //为了在对和错的两个按钮中分别写两次,单独写个私有方法    private void isCorrect(boolean userSelect)    {        if(questions[mCurrentId].isAnwserShown())            Toast.makeText(QuizActivity.this,"不能作弊呀",Toast.LENGTH_SHORT).show();        else {            if (userSelect == questions[mCurrentId].isAnwserTure())                Toast.makeText(QuizActivity.this, R.string.correct, Toast.LENGTH_SHORT).show();            else                Toast.makeText(QuizActivity.this, R.string.wrong, Toast.LENGTH_SHORT).show();        }    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    //Log.d(TAG, "onCreate: mCurrentId="+mCurrentId);        setContentView(R.layout.activity_quiz);        mCurrentId=0;        //Log.d(TAG, "onCreate: mCurrentId="+mCurrentId);        mTrueButton=(Button)findViewById(R.id.true_button);        mFalseButton=(Button)findViewById(R.id.false_button);        mNextButton=(ImageButton)findViewById(R.id.next_button);        mPreButton=(ImageButton)findViewById(R.id.pre_button);        mSeeAnswer=(Button)findViewById(R.id.see_answer_button);        mTextView=(TextView)findViewById(R.id.quiz_textView);        mTrueButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                isCorrect(true);            }        });        mFalseButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {               isCorrect(false);            }        });        mNextButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //记得下一题的时候要重置是否作弊(之前是否偷看跟activity绑定而不是跟题目绑定的时候)                mCurrentId=(mCurrentId+1)%questions.length;                updateQuestion(mCurrentId);            }        });        mPreButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mCurrentId=(mCurrentId-1+questions.length)%questions.length;                updateQuestion(mCurrentId);            }        });        mTextView.setOnClickListener(new View.OnClickListener(){            @Override            public void onClick(View view){                mCurrentId=(mCurrentId+1)%questions.length;                updateQuestion(mCurrentId);            }        });        //记得相应的横屏显示也要填上新增组件        mSeeAnswer.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent=AnswerActivity.NewIntent(QuizActivity.this,questions[mCurrentId].isAnwserTure());                startActivityForResult(intent,REQUEST_CODE_ANSWER);            }        });        if(savedInstanceState!=null){            //两个参数,键值和默认值            mCurrentId=savedInstanceState.getInt(KEY_INDEX,0);        }   //Log.d(TAG, "onCreate: mCurrentId="+mCurrentId);        updateQuestion(mCurrentId);    }    @Override    public void onSaveInstanceState(Bundle savedInstanceState)    {        super.onSaveInstanceState(savedInstanceState);        Log.d(TAG, "onSaveInstanceState: ");        savedInstanceState.putInt(KEY_INDEX,mCurrentId);        //之前是否偷看是跟activity绑定的 时候还要防止旋转屏幕之后偷看值重置        //savedInstanceState.putBoolean(IS_ANSWER_SHOWN,mIsCheat);    }    @Override    protected void onActivityResult(int requestCode,int resultCode,Intent data)    {        if(requestCode==0)        {            if(resultCode==RESULT_OK)            {                questions[mCurrentId].setAnwserShown(AnswerActivity.IsCheat(data));            }        }    }}

questions的初始化语句虽然写在onCreate的外面,但调试发现当旋转屏幕onCreate重新执行时,questions重新初始化了一次,猜测这个初始化是在onCreate中执行的,这就导致将是否看过答案与题目绑定,并不能解决旋转屏幕后重置该值的问题。||疑问:onCreate的前几句中有:mCurrentId=0;(虽然这是一句写错的没有用的代码)但实际允许的状态下旋转一下屏幕,题目并不会变成第一题,添加了三句调试代码后,在三个位置输出的mCurrentId分别时0,0,1。这是怎么回事,原始数据恢复到底是在什么时候执行的?======所以就是在update前面那个if(savedInstanceState)里执行了啊,这个要自己去取出来的不。`
最前面调用超类方时自动赋值的||将newIntent作为要到达的子Activity的方法,这样便于在父Activity中调用时可清晰的看到需要什么参数。||既然有重写onSaveInstanceState方法的话,久别忘了在onCreate里判断savedInstanceState为不为空,并把值取出来。

public class AnswerActivity extends AppCompatActivity {    private static final String TAG = "AnswerActivity";    private TextView mAnswerText;    private Button mSureButton;    private boolean isAnswerShow=false;    private boolean answer;    private  static final String CHEAT_KEY="com.example.purplefirstreview.Cheat";    //别漏双引号    private static final String AnswerKey="com.example.purplefirstreview.isAnswerTrue";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_answer);        mSureButton=(Button)findViewById(R.id.sure_button);        mAnswerText=(TextView) findViewById(R.id.answer_text);        answer=getIntent().getBooleanExtra(AnswerKey,false);        if(savedInstanceState!=null)        {            isAnswerShow=savedInstanceState.getBoolean(CHEAT_KEY,false);        }        Log.d(TAG, "isAnswerShow="+isAnswerShow);        if(isAnswerShow)            if(answer)                mAnswerText.setText("对");            else                mAnswerText.setText("错");        mSureButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                isAnswerShow=true;                    if(answer)                        mAnswerText.setText("对");                    else                        mAnswerText.setText("错");                setAnswerResult(RESULT_OK);            }        });    }    @Override    public void onSaveInstanceState(Bundle savedInstanceState)    {        super.onSaveInstanceState(savedInstanceState);        savedInstanceState.putBoolean(CHEAT_KEY,isAnswerShow);    }    private void setAnswerResult(int resultCode)    {        Intent intent=new Intent();        intent.putExtra(CHEAT_KEY,true);        setResult(resultCode,intent);    }    //注意这里要返回Intent    public static Intent NewIntent(Context context,boolean isAnswerTure)    {        Intent intent=new Intent(context,AnswerActivity.class);        intent.putExtra(AnswerKey,isAnswerTure);        return intent;    }    public static boolean IsCheat(Intent intent)    {        return intent.getBooleanExtra(CHEAT_KEY,false);    }}

注意子Activity返回是否作弊给父Activity时,虽然有传回带了boolean值的intent的,但这个intent的键是在子Activity里定义的,所以判断是否作弊应该作为子Activity的公有方法。