008 Android programming 3rd Activity life cycle and debug processing

Keywords: Android xml encoding

Chapter III Activity Life Cycle

Every time you rotate the screen, you jump to the first question.

life cycle

What exactly should onCreate do?

Typically, an activity overrides onCreate(Bundle) to prepare the
specifics of its UI:

1. inflating widgets and putting them on screen (in the call to (setContentView(int))

2. getting references to inflated widgets

3. setting listeners on widgets to handle user interaction

4. connecting to external model data


package com.audio.android.geoquiz;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class QuizActivity extends AppCompatActivity {

    private static final String TAG = "QuizActivity";

    private Button mTrueButton;
    private Button mFalseButton;
    private Button mPrevButton;
    private Button mNextButton;
    private TextView mQuestionTextView;

    private Question[] mQuestionBank = new Question[] {
            new Question(R.string.question_australia, true),
            new Question(R.string.question_oceans, true),
            new Question(R.string.question_mideast,false),
            new Question(R.string.question_africa, false),
            new Question(R.string.question_americas, true),
            new Question(R.string.question_asia, true),
    };

    private int mCurrentIndex = 0;

    //Toast correctToast = Toast.makeText(QuizActivity.this, R.string.correct_toast, Toast.LENGTH_SHORT);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate (Bundle) called");
        setContentView(R.layout.activity_quiz);

        mQuestionTextView = (TextView) findViewById(R.id.question_text_view);
        updateQuestion();

        mQuestionTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mCurrentIndex = (mCurrentIndex + 1) % mQuestionBank.length;
                updateQuestion();
            }
        });

        mTrueButton = (Button) findViewById(R.id.true_button);
        mTrueButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                checkAnswer(true);
            }
        });

        mFalseButton = (Button) findViewById(R.id.false_button);
        mFalseButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                checkAnswer(false);
            }
        });

        mPrevButton = (Button) findViewById(R.id.prev_button);
        mPrevButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mCurrentIndex = mCurrentIndex - 1 < 0 ? (mCurrentIndex - 1 + mQuestionBank.length) : mCurrentIndex - 1;
                mCurrentIndex = mCurrentIndex % mQuestionBank.length;
                updateQuestion();
            }
        });

        mNextButton = (Button) findViewById(R.id.next_button);
        mNextButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mCurrentIndex = (mCurrentIndex + 1) % mQuestionBank.length;
                updateQuestion();
            }
        });
    }
    private void updateQuestion() {
        int question = mQuestionBank[mCurrentIndex].getTextResId();
        mQuestionTextView.setText(question);
    }

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

        int messageResId = 0;
        if (userPressedTrue == answerIsTrue) {
            messageResId = R.string.correct_toast;
        } else {
            messageResId = R.string.incorrect_toast;
        }
        Toast.makeText(this, messageResId, Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "onStart() called");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume() called");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause() called");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "onStop() called");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy() called");
    }
}

The order of calls when clicking on Open and Return keys.

06-25 15:05:25.638 30412-30412/com.audio.android.geoquiz D/QuizActivity: onCreate (Bundle) called
06-25 15:05:25.758 30412-30412/com.audio.android.geoquiz D/QuizActivity: onStart() called
06-25 15:05:25.761 30412-30412/com.audio.android.geoquiz D/QuizActivity: onResume() called

06-25 15:05:35.420 30412-30412/com.audio.android.geoquiz D/QuizActivity: onPause() called
06-25 15:05:35.831 30412-30412/com.audio.android.geoquiz D/QuizActivity: onStop() called
06-25 15:05:35.831 30412-30412/com.audio.android.geoquiz D/QuizActivity: onDestroy() called

You can see clearly how functions are called.

Call the function of the parent class before starting the callback

These superclass calls are required. Calling the superclass implementation should be the first line of each callback method override implementation.

Pressing the home key has some effect

This means, after pressing Home, your instance of QuizActivity hangs out in the stopped state (in memory, not visible, and not active in the foreground).

Open Programs from Recent Menus

A quick look at Logcat shows that your activity got calls to onStart() and onResume().

Equipment configuration

Rotating the device changes the device configuration. The device configuration is a set of characteristics that describe the current state of an individual device. The characteristics that make up the configuration include screen orientation screen density, screen size, keyboard type, dock mode, language, and more.


Create a banner screen

Introduction to FrameLayout

FrameLayout is the simplest ViewGroup and does not arrange its children in any particular manner. In this layout, child views will be arranged according to their

android:layout_gravity attributes.

The onSave Instance State (Bundle out State) method needs to be rewritten because the data will be lost when the screen is horizontal or vertical.

Note that the types that you can save to and restore from a Bundle are primitive types and classes that implement the Serializable or Parcelable interface.

Two challenges, one is to enable/disable the corresponding button, complete.

Print the score and write it.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id = "@+id/question_text_view"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:layout_gravity = "center_horizontal"
        android:padding = "24dp" />

    <LinearLayout
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:layout_gravity = "center_vertical|center_horizontal"
        android:padding = "20dp"
        android:orientation = "horizontal" >

        <Button
            android:id = "@+id/true_button"
            android:layout_width = "wrap_content"
            android:layout_height = "wrap_content"
            android:text = "@string/true_button" />

        <Button
            android:id = "@+id/false_button"
            android:layout_width = "wrap_content"
            android:layout_height = "wrap_content"
            android:text = "@string/false_button"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:layout_gravity = "bottom|right"
        android:orientation = "horizontal" >
        <Button
            android:id="@+id/prev_button"
            android:layout_width = "wrap_content"
            android:layout_height = "wrap_content"
            android:text = "@string/prev_button"
            android:drawableLeft = "@drawable/arrow_left"
            android:drawablePadding = "4dp"/>

        <Button
            android:id="@+id/next_button"
            android:layout_width = "wrap_content"
            android:layout_height = "wrap_content"
            android:text = "@string/next_button"
            android:drawableRight = "@drawable/arrow_right"
            android:drawablePadding = "4dp"/>

        </LinearLayout>

    <LinearLayout
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:orientation = "horizontal" >

        <ImageButton
            android:id="@+id/prev_img_button"
            android:layout_width = "wrap_content"
            android:layout_height = "wrap_content"
            android:src = "@drawable/arrow_left"
            android:contentDescription="@string/previous_question"/>

        <ImageButton
            android:id="@+id/next_img_button"
            android:layout_width = "wrap_content"
            android:layout_height = "wrap_content"
            android:src = "@drawable/arrow_right"
            android:contentDescription="@string/next_question"/>

    </LinearLayout>

</FrameLayout>

package com.audio.android.geoquiz;

import android.os.PersistableBundle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class QuizActivity extends AppCompatActivity {

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

    private Button mTrueButton;
    private Button mFalseButton;
    private Button mPrevButton;
    private Button mNextButton;
    private TextView mQuestionTextView;

    private Question[] mQuestionBank = new Question[] {
            new Question(R.string.question_australia, true),
            new Question(R.string.question_oceans, true),
            new Question(R.string.question_mideast,false),
            new Question(R.string.question_africa, false),
            new Question(R.string.question_americas, true),
            new Question(R.string.question_asia, true),
    };

    private int mCurrentIndex = 0;

    private int isRight = 0;
    private int isWrong = 0;

    //Toast correctToast = Toast.makeText(QuizActivity.this, R.string.correct_toast, Toast.LENGTH_SHORT);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate (Bundle) called");
        setContentView(R.layout.activity_quiz);

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

        mQuestionTextView = (TextView) findViewById(R.id.question_text_view);
        int question = mQuestionBank[mCurrentIndex].getTextResId();
        mQuestionTextView.setText(question);

        mQuestionTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mCurrentIndex = (mCurrentIndex + 1) % mQuestionBank.length;
                updateQuestion();
            }
        });

        mTrueButton = (Button) findViewById(R.id.true_button);
        mTrueButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                checkAnswer(true);
            }
        });

        mFalseButton = (Button) findViewById(R.id.false_button);
        mFalseButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                checkAnswer(false);
            }
        });

        mPrevButton = (Button) findViewById(R.id.prev_button);
        mPrevButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mCurrentIndex = mCurrentIndex - 1 < 0 ? (mCurrentIndex - 1 + mQuestionBank.length) : mCurrentIndex - 1;
                mCurrentIndex = mCurrentIndex % mQuestionBank.length;
                updateQuestion();
            }
        });

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

        int question = mQuestionBank[mCurrentIndex].getTextResId();
        mQuestionTextView.setText(question);
    }

    private void checkAnswer(boolean userPressedTrue) {
        mTrueButton.setClickable(false);
        mFalseButton.setClickable(false);

        boolean answerIsTrue = mQuestionBank[mCurrentIndex].isAnswerTrue();

        int messageResId = 0;
        if (userPressedTrue == answerIsTrue) {
            messageResId = R.string.correct_toast;
            isRight++;
        } else {
            messageResId = R.string.incorrect_toast;
            isWrong++;
        }
        Toast.makeText(this, messageResId, Toast.LENGTH_SHORT).show();
        if ((isRight + isWrong) % mQuestionBank.length == 0)
            Toast.makeText(this, "percentage score " + ((float)isRight)/(isRight + isWrong), Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "onStart() called");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume() called");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause() called");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.i(TAG, "onSaveInstanceState");
        outState.putInt(KEY_INDEX, mCurrentIndex);
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "onStop() called");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy() called");
    }
}

screenshot


Posted by hoogie on Sun, 10 Feb 2019 20:54:17 -0800