Java安卓学习总结(七)

activity的生命周期(1/1)

有关复制Project文件夹

原本我是打算就将挑战练习就写在原先的项目里面,但是发现实在是容易搞乱原先的项目。于是我就将本来的项目文件夹复制了一份。打开后发现出现了这个问题

上网查询之后发现需要重构项目。

1.Build->Clean Project

2.Build->Rebuild Project

有关水平模式布局

水平模式布局作为备选资源,我在想它的命名是否有一定的规范。查阅开发者手册之后我发现命名是固定的,我也不知道为什么我会有这种疑问。

有关gravity和layout_gravity

出现了两个长得很像的属性gravity和layout_gravity

我很是很迷惑这两者的区别,所以上网查询,结果如下:

原帖

gravity的中文意思就是”重心“,就是表示view横向和纵向的停靠位置

  (1).android:gravity:是对view控件本身来说的,是用来设置view本身的内容应该显示在view的什么位置,默认值是左侧。也可以用来设置布局中的控件位置

  (2).android:layout_gravity:是相对于包含改元素的父元素来说的,设置该元素在父元素的什么位置;

  比如TextView: android:layout_gravity表示TextView在界面上的位置,android:gravity表示TextView文本在TextView的什么位置,默认值是左侧.

至于为什么在下图中使用layout_gravity无效(我原本以为按钮会偏下偏右),

查询之后发现当设置 android:orientation=”horizontal” ,水平方向的设置都是无效的,只有top和bottom设置有效果。并且想要达到效果需要配合使用layout_weight。原帖

虽然很丑。

有关开发者选项

在研究activity内存清理现状时要用到开发者选项,图中为开启流程。

Seethings中选择About Phone

找到安卓版本Build number

狂点数次之后会出现提示

返回Settings界面就可以开启了。

有关LogCat日志

旋转屏幕与开启开发者选项中的Don’t keep activities选项后单击退出键,日志均显示如下:

05-20 12:04:30.240 2652-2652/com.example.a73421.geoquiz D/QuizActivity: onPause() called
05-20 12:04:30.673 2652-2652/com.example.a73421.geoquiz I/QuizActivity: saveInstanceState
05-20 12:04:30.673 2652-2652/com.example.a73421.geoquiz D/QuizActivity: onStop() called
05-20 12:04:30.688 2652-2652/com.example.a73421.geoquiz D/QuizActivity: onDestory() called
05-20 12:04:32.124 2652-2652/com.example.a73421.geoquiz D/QuizActivity: onCreate(Bundle) called
05-20 12:04:32.129 2652-2652/com.example.a73421.geoquiz D/QuizActivity: onStart() called
05-20 12:04:32.129 2652-2652/com.example.a73421.geoquiz D/QuizActivity: onResume() called

activity状态均在onPause()被调用后就被记录了。原因是调用过onStop()后activity随时都可能会被摧毁,所以必须在其之前记录。

有关挑战练习

禁止一题多答

给Question类增加一个成员变量

private boolean mAnswered;

用于记录是否已经做过这道题目。

public class Question {
    private int mTextResId;
    private boolean mAnswerTrue;
    private boolean mAnswered;
    public Question(int TextResId, boolean AnswerTrue,boolean Answered)
    {
        mTextResId=TextResId;
        mAnswerTrue=AnswerTrue;
        mAnswered=Answered;
    }

    public boolean isAnswered() {
        return mAnswered;
    }

    public void setAnswered(boolean answered) {
        mAnswered = answered;
    }
    //...
}

对于每一个题目,其答案按钮是否被禁用取决于其是否被回答过。需要在updateQuestion()方法中增加次功能,并且在选择到已经回答过的题目给出toast提示。

private void updateQuestion()
{
    if (mQuestionBank[mCurrentIndex].isAnswered())
    {
        int messageResId;
        messageResId=R.string.cannot_answer_again;
        Toast.makeText(this,messageResId,Toast.LENGTH_SHORT).show();
        mTrueButton.setEnabled(false);
        mFalseButton.setEnabled(false);
    }
    else
    {
        mTrueButton.setEnabled(true);
        mFalseButton.setEnabled(true);
    }
    int question=mQuestionBank[mCurrentIndex].getTextResId();
    mQuestionQtextview.setText(question);
}

然后修改checkAnswer()方法,使得每次调用次方法后,对应题目的按钮被禁用,对应的题目标记为已经回答过。

private void checkAnswer(boolean userPressedTrue)
{
    int messageResId=0;
    boolean answerIsTrue=mQuestionBank[mCurrentIndex].isAnswerTrue();
    if (userPressedTrue==answerIsTrue)
    {
        messageResId=R.string.correct_toast;
    }
    else
    {
        messageResId=R.string.incorrect_toast;
    }
    mTrueButton.setEnabled(false);
    mFalseButton.setEnabled(false);
    mQuestionBank[mCurrentIndex].setAnswered(true);
    Toast.makeText(this,messageResId,Toast.LENGTH_SHORT).show();
}

结果测试之后,发现旋转屏幕前可以达到禁止多答的功能。但是旋转屏幕之后不能了,所以还要将回答去状态存储到activity记录中,并修改onSaveInstanceState()方法。

需要先新建一个键

private static final String KEY_ANSWERED="answered";

然后在onSaveInstanceState()方法中存储所有问题的回答状态。

protected void  onSaveInstanceState(Bundle saveInstanceState)
{
    super.onSaveInstanceState(saveInstanceState);
    Log.i(TAG,"saveInstanceState");
    boolean IsAnswered[]=new boolean[mQuestionBank.length];
    for (int i=0;i<mQuestionBank.length;i++)
    {
        IsAnswered[i]=mQuestionBank[i].isAnswered();
    }
    saveInstanceState.putInt(KEY_INDEX,mCurrentIndex);
    saveInstanceState.putBooleanArray(KEY_ANSWERED,IsAnswered);
}

评分

需要增加两个成员变量,mNum记录已经回答的题目数量,mScore记录已经回答正确的数量。这两个变量全在checkAnswer()方法中维护。每当一个问题被回答时,mNum自增;每当一个问题被回答对时,mScore自增。当mNum==mQuestionBank.lenth时输出答案。同样的这两个成员变量也要被及时存储在activity记录里面。

private void checkAnswer(boolean userPressedTrue)
    {
        int messageResId=0;
        boolean answerIsTrue=mQuestionBank[mCurrentIndex].isAnswerTrue();

        if (userPressedTrue==answerIsTrue)
        {
            mScore++;
            messageResId=R.string.correct_toast;
        }
        else
        {
            messageResId=R.string.incorrect_toast;
        }
        mNum++;

        mTrueButton.setEnabled(false);
        mFalseButton.setEnabled(false);
        mQuestionBank[mCurrentIndex].setAnswered(true);
        Toast.makeText(this,messageResId,Toast.LENGTH_SHORT).show();
        if (mNum==mQuestionBank.length)
        {
            double score=100.0*mScore/mNum;
            String scoreText="你的正确率为"+score+"%";
            Toast.makeText(this,scoreText,Toast.LENGTH_SHORT).show();
        }
    }

发表评论