Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Fragment生命周期詳解

Fragment生命周期詳解

編輯:關於Android編程

1. Fragment概述

Fragment從Android v3.0版本開始引入

隨著界面布局的復雜化,處理起來也更加的復雜,引入Fragment可以把activity拆分成各個部分。每個Fragment都有它自己的布局和生命周期。方便了開發。

采用fragment而不是activity進行應用的UI管理,可繞開Android系統activity規則的限制。

fragment是一種控制器對象,activity可委派它完成一些任務通常這些任務就是管理用戶界面。受管的用戶界面可以是一整屏或是整屏的一部分。管理用戶界面的fragment又稱為UI fragment。它也有自己產生於布局文件的視圖。fragment視圖包含了用戶可以交互的可視化UI元素。

activity托管fragment,暫時可以把托管理解成activity在其視圖層級裡提供一處位置來放置fragment的視圖。fragment本身不具有在屏幕上顯示視圖的能力,因此,只有將它的視圖放置在activity的視圖層級結構中,fragment視圖才能顯示在屏幕上。

使用 Fragment 的好處就是可以把業務邏輯和 UI 封裝在一起,與外部關聯系不大, 其他程序也可以用該組件,從而實現復用最大化。

2. 兩種方式加入Fragment

首先創建 Demo3Fragment 繼承 Fragment 類, 並為其創建xml布局文件

package com.ashzheng.studydemo.demo3;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.ashzheng.studydemo.R;

public class Demo3Fragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_demo3, container, false);

        return view;
    }
}

1. 通過XML標簽

在activity的xml布局文件中添加節點

    

2. 通過代碼動態創建

在activity的xml布局文件中添加容器視圖

<framelayout android:id="@+id/demo3_layout" android:layout_height="0dp" android:layout_weight="1" android:layout_width="match_parent">
</framelayout>

在activity中動態添加fragment

package com.ashzheng.studydemo.demo3;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;

import com.ashzheng.studydemo.R;

public class Demo3Activity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo3);


        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.demo3_layout, new Demo3Fragment());
        fragmentTransaction.commit();
    }

}

3. Fragment生命周期

\

fragment生命周期類似於activity的生命周期。生命周期方法的對應非常重要,因為fragment代表activity在工作,它的狀態應該也反應了activity的狀態。因而,fragment需要對應的生命周期方法來處理activity的工作。

這些方法的作用會在代碼中的注釋給出

Fragment                                      

1. 界面打開                 
    onCreate() 方法執行!                
    onCreateView() 方法執行!             
    onActivityCreated() 方法執行!   
    onStart() 方法執行!
    onResume() 方法執行!

2. 按下主屏幕鍵/鎖屏        
    onPause() 方法執行!
    onStop() 方法執行!

3. 重新打開
    onStart() 方法執行!
    onResume() 方法執行!

4. 按下後退鍵
    onPause() 方法執行!
    onStop() 方法執行!
    onDestroyView() 方法執行!
    onDestroy() 方法執行!
    onDetach() 方法執行!

Activity
    1. 打開應用
    onCreate() 方法執行!
    onStart() 方法執行!
    onResume() 方法執行!

    2. 按下主屏幕鍵/鎖屏
    onPause() 方法執行!
    onStop() 方法執行!

    3. 重新打開應用
    onRestart() 方法執行!
    onStart() 方法執行!
    onResume() 方法執行!

    4. 按下後退鍵
    onPause() 方法執行! 
    onStop() 方法執行!  
    onDestroy() 方法執行!

在Activity中加入Fragment,對應的生命周期
1. 打開
Fragment onCreate() 方法執行!
Fragment onCreateView() 方法執行!
Activity onCreate() 方法執行!
Fragment onActivityCreated() 方法執行!
Activity onStart() 方法執行!
Fragment onStart() 方法執行!
Activity onResume() 方法執行!
Fragment onResume() 方法執行!

2. 按下主屏幕鍵/鎖屏
Fragment onPause() 方法執行!
Activity onPause() 方法執行!
Fragment onStop() 方法執行!
Activity onStop() 方法執行!

3. 再次打開
Activity onRestart() 方法執行!
Activity onStart() 方法執行!
Fragment onStart() 方法執行!
Activity onResume() 方法執行!
Fragment onResume() 方法執行!

4. 按下後退鍵
Fragment onPause() 方法執行!
Activity onPause() 方法執行!
Fragment onStop() 方法執行!
Activity onStop() 方法執行!
Fragment onDestroyView() 方法執行!
Fragment onDestroy() 方法執行!
Fragment onDetach() 方法執行!
Activity onDestroy() 方法執行!

activity的FragmentManager負責調用隊列中fragment的生命周期方法,添加fragment供FragmentManager管理時,onAttach(Activity)、onCreat(Bundle)以及onCreatView()方法會被調用。

托管activity的onCreate()方法執行後,onActivityCreated()方法也會被調用。因為正在向Activity.onCreat()方法中添加fragment,所以fragment被添加後,該方法會被調用。

在activity處於停止、暫停或運行狀態下時,添加fragment會發生什麼呢?此種情況下,FragmentManager立即驅使fragment快速跟上activity的步伐,直到與activity的最新狀態保持同步。例如,向運行狀態的activity中添加fragment時,以下fragment生命周期方法會被依次調用:onAttch()、onCreat()、onCreatView()、onActivityCreated()、onStart(),以及onResume()方法。

只要fragment的狀態與activity的狀態保持了同步,托管activity的FragmentManager便會繼續調用其他生命周期方法以繼續保持fragment與activity的狀態一致,而幾乎同時,它接收到了從操作系統發出的相應調用。但fragment方法究竟是在activity方法之前還是之後調用的這一點是無法保證的。

fragment生命周期與activity生命周期的一個關鍵區別就在於,fragment的生命周期方法是由托管activity而不是操作系統調用的。操作系統無從知曉activity用來管理視圖的fragment。fragment的使用是activity自己內部的事情。可以發現,activity中的生命周期方法都是protected,而fragment的則是public,這就是因為fragment是由activity來管理的,activity需要調用這些個方法。

4.Fragment中的數據保存

和在activity中一樣,fragment也提供了onSaveInstanceState()方法,使用也基本和activity一樣,不同的是,在fragment中,雖然Fragment.onCreate()方法配置了fragment實例,但創建和配置fragment視圖是通過Fragment.onCreateView()方法來完成的。所以可以在Fragment.onCreateView()這個方法中獲取在保存狀態下重建視圖所使用的數據。

具體代碼:

Demo3Fragment

package com.ashzheng.studydemo.demo3;

import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.ashzheng.studydemo.R;

public class Demo3Fragment extends Fragment {

    @Override
    public void onAttach(Context context) {
        //當fragment 第一次與 Activity 產生關聯時調用,以後不再調用
        super.onAttach(context);
        Log.d("demoinfo", "Fragment onAttach() 方法執行!");
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        //在 onAttach 執行完後會立刻調用此方法,通常被用於讀取保存的狀態值,獲取或者初始化一些數據,
        // 但是該方法不執行,窗口是不會顯示的,因此如果獲取的數據需要訪問網絡,最好新開線程。
        super.onCreate(savedInstanceState);
        Log.d("demoinfo", "Fragment onCreate() 方法執行!");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //創建 Fragment 中顯示的 view, 其中 inflater 用來裝載布局文件, container 表示  標簽的父標簽對應的 ViewGroup 對象,
        // savedInstanceState 可以獲取 Fragment 保存的狀態

        Log.d("demoinfo", "Fragment onCreateView() 方法執行!");

        if(null != savedInstanceState){
            Log.d("demoinfo", "保存了的數據: "+ savedInstanceState.getString("myinfo"));
        }else {
            Log.d("demoinfo", "沒有保存的數據!");
        }

        View view = inflater.inflate(R.layout.fragment_demo3, container, false);

        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        //在 Activity.onCreate() 方法調用後會立刻調用此方法,表示窗口已經初始化完畢,此時可以調用控件了

        super.onActivityCreated(savedInstanceState);
        Log.d("demoinfo", "Fragment onActivityCreated() 方法執行!");
    }

    @Override
    public void onStart() {
        //開始執行與控件相關的邏輯代碼,如按鍵點擊
        super.onStart();
        Log.d("demoinfo", "Fragment onStart() 方法執行!");
    }

    @Override
    public void onResume() {
        //這是 Fragment 從創建到顯示的最後一個回調的方法
        super.onResume();
        Log.d("demoinfo", "Fragment onResume() 方法執行!");
    }

    @Override
    public void onPause() {
        //當發生界面跳轉時,臨時暫停,暫停時間是 500ms,0.5s後直接進入下面的 onStop 方法
        super.onPause();
        Log.d("demoinfo", "Fragment onPause() 方法執行!");
    }

    @Override
    public void onStop() {
        //當該方法返回時, Fragment 將從屏幕上消失
        super.onStop();
        Log.d("demoinfo", "Fragment onStop() 方法執行!");
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.d("demoinfo", "Fragment onSaveInstanceState() 方法執行!");
        outState.putString("myinfo", "haha");
    }

    @Override
    public void onDestroyView() {
        //當 fragment 狀態被保存,或者從回退棧彈出,該方法被調用
        super.onDestroyView();
        Log.d("demoinfo", "Fragment onDestroyView() 方法執行!");
    }

    @Override
    public void onDestroy() {
        //當 Fragment 不再被使用時,如按返回鍵,就會調用此方法
        super.onDestroy();
        Log.d("demoinfo", "Fragment onDestroy() 方法執行!");
    }

    @Override
    public void onDetach() {
        //Fragment 生命周期的最後一個方法,執行完後將不再與 Activity 關聯,將釋放所有 fragment 對象和資源
        super.onDetach();
        Log.d("demoinfo", "Fragment onDetach() 方法執行!");
    }
}

Demo3Activity

package com.ashzheng.studydemo.demo3;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.util.Log;

import com.ashzheng.studydemo.R;

public class Demo3Activity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo3);

        Log.d("demoInfo", "Activity onCreate() 方法執行!");


//        FragmentManager fragmentManager = getFragmentManager();
//        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//        fragmentTransaction.add(R.id.demo3_layout, new Demo3Fragment());
//        fragmentTransaction.commit();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("demoInfo", "Activity onDestroy() 方法執行!");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("demoInfo", "Activity onPause() 方法執行!");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("demoInfo", "Activity onRestart() 方法執行!");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("demoInfo", "Activity onStart() 方法執行!");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("demoInfo", "Activity onStop() 方法執行!");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("demoInfo", "Activity onResume() 方法執行!");

    }

}

activity_demo3.xml

<code><linearlayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" tools:context="com.ashzheng.studydemo.demo3.Demo3Activity" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">

    <fragment android:id="@+id/demo3_fg" android:layout_height="0dp" android:layout_weight="1" android:layout_width="match_parent" android:name="com.ashzheng.studydemo.demo3.Demo3Fragment">
    <framelayout android:id="@+id/demo3_layout" android:layout_height="0dp" android:layout_weight="1" android:layout_width="match_parent"> 

</framelayout></fragment></linearlayout>
</code>

總項目地址:https://github.com/zhenggy/AndroidStudyDemo

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved