Android编程权威指南范例---步骤2--日志跟踪理解activity生命周期

Activity的生命周期有6个,分别是onCreate(Bundle),onStart(),onResume(),onPause(),onStop(),onDestory().
1. 在创建实例时,首先调用onCreate(Bundle),onStart(),onResume()这三个生命周期方法,当摧毁实例时,比如后退,就会调用onPause(),onStop(),onDestory()这三个方法销毁实例
2. 创建实例以后,如果这时候按主屏幕键,就会退出,但是这时候并不会销毁实例,会调用onPause(),onStop()方法,不会调用onDestory()方法,当再次打开应用,会调用onStart(),onResume()方法,系统重新启动,继续运行,不会调用onCreate(Bundle)方法,因为先前的退出并没有销毁实例,所以也就不需要重新创建实例。

接下来我们在步骤一的基础上继续实现,先前有一个问题就是旋转屏幕会销毁实例,接下来我们要解决这个问题。
步骤一链接: https://blog.csdn.net/ayangann915/article/details/81144948

每当旋转屏幕,当前activity就会被销毁,会创建新的activity,存储的问题的索引值也会重新赋值为0,又会回到第1个问题。

具体实现

布局可分为水平布局和竖直布局,因为要旋转屏幕,所以我们可以设计两种布局,即水平布局和竖直布局。下面是水平布局的xml文件代码:

<?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:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="24dp"
        android:layout_gravity="center_horizontal"
        android:id="@+id/question_next_view"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|center_vertical">

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

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

   <FrameLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_gravity="bottom">


       <ImageButton
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:src="@drawable/arrow_left"
           android:id="@+id/last_button"
           android:layout_gravity="bottom|left"/>

       <ImageButton
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:id="@+id/next_button"
           android:src="@drawable/arrow_right"
           android:layout_gravity="bottom|right"/>
       <!--android:text="@string/next"-->
       <!--android:drawableRight="@drawable/arrow_right"/>-->

   </FrameLayout>
</FrameLayout>

这里我们换成了FrameLayout,framelayout里面组件的位置只取决于layout-gravity属性,所以我们要为各组件设置layout-gravity值。

因为旋转屏幕后index值的数据没有保存,所以我们要想办法将其保存,一般我们将其存储在bundle中,通过onSaveInstanceState(Bundle outstate)方法,因为存储的index是int类型,存储方式为键值对,所以通过getInt()和putInt()来设置,在onSaveInstanceState方法中存储后,还要在increase方法中获取bundle存储的值,如果怕不为空,就把这个值赋值给mcurrentIndex。

import android.os.Bundle;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import org.w3c.dom.Text;


public class QuizeActivity extends AppCompatActivity {

    private Button true_btn,false_btn;
    private TextView mQuestion_text;
    private ImageButton next_btn,last_btn;
    private static String TAG="QuizeActivity";
    private static String KEY_INEX="index";
    //创建question对象数组
    private Question[] mQuestions=new Question[]{
            new Question(R.string.question_one,true),
            new Question(R.string.question_two,true),
            new Question(R.string.question_three,false),
            new Question(R.string.question_four,false)
    };
    //创建数组索引
    private int mCurrentIndex=0;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG,"onCreate() called");
        setContentView(R.layout.activity_quize);
//获取bundle值
        if(savedInstanceState!=null){
            mCurrentIndex=savedInstanceState.getInt(KEY_INEX,0);
        }

        true_btn=(Button)findViewById(R.id.true_button);
        false_btn=(Button)findViewById(R.id.false_button);
        mQuestion_text=(TextView)findViewById(R.id.question_next_view);
        next_btn=(ImageButton) findViewById(R.id.next_button);
        last_btn=(ImageButton)findViewById(R.id.last_button);
//        int question=mQuestions[mCurrentIndex].getTextResId();//string资源对象
//        mQuestion_text.setText(question);//设置问题的内容
        update();//设置初始问题

        true_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                checkAnswer(true);
            }
        });
        false_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                checkAnswer(false);
            }
        });
        next_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCurrentIndex=(mCurrentIndex+1)%mQuestions.length;
                update();
            }
        });

        last_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCurrentIndex=(mCurrentIndex-1)%mQuestions.length;
                update();
            }
        });
    }

    private void update(){
        int question=mQuestions[mCurrentIndex].getTextResId();
        mQuestion_text.setText(question);
    }

    private void checkAnswer(boolean userResult){
        boolean questionresult=mQuestions[mCurrentIndex].isAnswerTrue();
        int textResId=0;

        if(userResult==questionresult){
            textResId=R.string.correct_toast;
        }else{
            textResId=R.string.incorrect_toast;
        }

        Toast.makeText(this, textResId, Toast.LENGTH_SHORT).show();
    }

//生命周期的探讨
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG,"onDestory() called");
    }

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

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

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

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG,"onResume() called");
    }
//存储bundle值
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.d(TAG,"onSaveInstanceState() called");
        outState.putInt(KEY_INEX,mCurrentIndex);
    }
}

注意,bundle中存储的数据类型只能是基本类型以及可以实现Serializable或parcelable接口的对象。

猜你喜欢

转载自blog.csdn.net/ayangann915/article/details/81146236