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