Fragment淺談

前言

謝謝你那么的书劝、安靜的捧場墅拭。

Fragment的概述及其設(shè)計初衷

Fragment代表了Activity的子模塊歉铝,因此可以把Fragment理解成Activity片段宿亡。Fragment必須被“嵌入”Activity中使用碑诉,因此彪腔,雖然Fragment也擁有自己的生命周期,但Fragment的生命周期會受到它所在的Activity的生命周期控制进栽。只有當(dāng)該Activity處于活動狀態(tài)時漫仆,程序員才可通過方法獨立操作Fragment。
關(guān)于Fragment泪幌,可以歸納出如下幾個特征盲厌。
  • Fragment總是作為Activity界面的組成部分。Fragment可調(diào)用getActivity()方法獲取它所在的Activity祸泪,Activity可調(diào)用FragmentManager的findFragmentById()或findFragmentByTag()方法來獲取Fragment吗浩。

  • 在Activity運行過程中,可調(diào)用FragmentManager的add()没隘、remove()懂扼、replace()方法動態(tài)地添加、刪除或替換Fragment右蒲。

  • 一個Activity可以同時組合多個Fragment阀湿;反過來,一個Fragment也可被多個Activity復(fù)用瑰妄。

  • Fragment可以響應(yīng)自己的輸入事件陷嘴,并擁有自己的生命周期,但它們的生命周期直接被其所屬的Activity的生命周期控制间坐。

Fragment的初衷是為了適應(yīng)大屏幕的平板電腦灾挨,由于平板電腦的屏幕比手機(jī)屏幕更大,因此可以容納更多的UI組件竹宋,且這些UI組件之間存在交互關(guān)系劳澄。Fragment簡化了大屏幕UI的設(shè)計,它不需要開發(fā)者管理組件包含關(guān)系的復(fù)雜變化蜈七,開發(fā)者使用Fragment對UI組件進(jìn)行分組秒拔、模塊化管理,就可以更方便地在運行過程中動態(tài)更新Activity的用戶界面飒硅。

Fragment的生命周期

與Activity類似的是砂缩,F(xiàn)ragment也存在如下狀態(tài)。
  • 運行狀態(tài):當(dāng)前Fragment位于前臺狡相,用戶可見梯轻,可以獲得焦點。

  • 暫停狀態(tài):其他Activity位于前臺尽棕,該Fragment依然可見喳挑,只是不能獲得焦點。

  • 停止?fàn)顟B(tài):該Fragment不可見,失去焦點伊诵。

  • 銷毀狀態(tài):該Fragment被完全刪除单绑,或該Fragment所在的Activity被結(jié)束。

下圖顯示了Fragment的生命周期及相關(guān)回調(diào)方法曹宴。
lifecycle of fragment.png
從圖中可以看出搂橙,在Fragment的生命周期中,如下方法被系統(tǒng)回調(diào)笛坦。
  • onAttach():當(dāng)該Fragment被添加到Activity時被回調(diào)区转。該方法只會被調(diào)用一次。

  • onCreate():創(chuàng)建Fragment時被調(diào)用版扩。該方法只會被調(diào)用一次废离。

  • onCreateView():每次創(chuàng)建、繪制該Fragment的View組件時回調(diào)該方法礁芦,F(xiàn)ragment將會顯示該方法返回的View組件蜻韭。

  • onActivityCreated():當(dāng)Fragment所在的Activity被啟動完成后回調(diào)該方法。

  • onStart():啟動Fragment時被調(diào)用柿扣。

  • onResume():恢復(fù)Fragment時被回調(diào)肖方,在OnStart()方法后一定會調(diào)用onResume()方法。

  • onPause():暫停Fragment時被回調(diào)未状。

  • onStop():停止Fragment時被回調(diào)俯画。

  • onDestroyView():銷毀該Fragment所包含的View組件時調(diào)用。

  • onDestroy():銷毀該Fragment時被毀掉娩践。該方法只會調(diào)用一次活翩。

  • onDetach():將該Fragment從Activity中刪除、替換完成時回調(diào)該方法翻伺,在onDestroy()方法后一定會回調(diào)onDetach()方法。該方法只會被調(diào)用一次沮焕。

代碼示例

LifecycleFragment.java
public class LifecycleFragment extends Fragment {

    final String TAG = "--halo--";

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d(TAG, "---onActivityCreated---");
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Log.d(TAG, "---onAttach---");
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "---onCreate---");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "---onCreateView---");

        TextView tv = new TextView(getActivity());
        tv.setGravity(Gravity.CENTER_HORIZONTAL);
        tv.setText("測試Fragment");
        tv.setTextSize(40);
        return tv;
    }

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

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d(TAG, "---onDestroyView---");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d(TAG, "---onDetach---");
    }

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

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

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

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

LifecycleFgActivity.java
public class LifecycleFgActivity extends Activity {

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

        LifecycleFragment fragment = new LifecycleFragment();
        FragmentTransaction transaction = getFragmentManager().beginTransaction();
        transaction.replace(R.id.life_cycle, fragment).commit();

    }

    public void bt0(View v) {
        Intent intent = new Intent(this, DialogActivity.class);
        startActivity(intent);
    }

    public void bt1(View v) {
        LifecycleFragment fragment = new LifecycleFragment();
        FragmentTransaction transaction = getFragmentManager().beginTransaction();
        transaction.replace(R.id.life_cycle, fragment);
        transaction.addToBackStack(null);
        transaction.commit();

    }

    public void bt2(View v) {
        LifecycleFragment fragment = new LifecycleFragment();
        FragmentTransaction transaction = getFragmentManager().beginTransaction();
        transaction.replace(R.id.life_cycle, fragment);
        transaction.commit();
    }
}
lifecycle.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="bt0"
        android:text="打開對話框" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="bt1"
        android:text="替換目標(biāo)Fragment吨岭,并加入Back棧" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="bt2"
        android:text="退出" />
      <FrameLayout
        android:id="@+id/life_cycle"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

效果

當(dāng)使用Activity加載該Fragment時,可以在LogCat控制臺看到下圖的情況峦树。
lifecycle1.PNG
如果單擊程序中的“打開對話框”按鈕辣辫,將啟動一個對話框風(fēng)格的Activity,當(dāng)前的Activity將會轉(zhuǎn)入暫停狀態(tài)魁巩,該Fragment已經(jīng)進(jìn)入“暫图泵穑”狀態(tài),此時可以在LogCat控制臺看到下圖的情況谷遂。
lifecycle2.PNG
關(guān)閉對話框風(fēng)格的Activity葬馋,F(xiàn)ragment將會再次進(jìn)入“運行”狀態(tài),將可以在LogCat控制臺看到下圖的情況。
lifecycle3.PNG
單擊程序界面上的“替換目標(biāo)Fragment畴嘶,并加入Back椀坝猓”,將可以在LogCat控制臺看到如下圖的情況窗悯。
lifecycle4.PNG
當(dāng)你點擊手機(jī)上的返回按鈕時区匣,該fragment將會再次顯示出來,此時可以在LogCat控制臺看到如下圖的情況蒋院。
lifecycle5.PNG
單擊程序界面上的“退出”按鈕亏钩,該Fragment將會被完全結(jié)束,F(xiàn)ragment將進(jìn)入“銷毀”狀態(tài)欺旧,此時可以在LogCat控制人看到如下圖的情況姑丑。
lifecycle6.PNG
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市切端,隨后出現(xiàn)的幾起案子彻坛,更是在濱河造成了極大的恐慌,老刑警劉巖踏枣,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昌屉,死亡現(xiàn)場離奇詭異,居然都是意外死亡茵瀑,警方通過查閱死者的電腦和手機(jī)间驮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來马昨,“玉大人竞帽,你說我怎么就攤上這事『枧酰” “怎么了屹篓?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長匙奴。 經(jīng)常有香客問我堆巧,道長,這世上最難降的妖魔是什么泼菌? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任谍肤,我火速辦了婚禮,結(jié)果婚禮上哗伯,老公的妹妹穿的比我還像新娘荒揣。我一直安慰自己,他們只是感情好焊刹,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布系任。 她就那樣靜靜地躺著恳蹲,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赋除。 梳的紋絲不亂的頭發(fā)上阱缓,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機(jī)與錄音举农,去河邊找鬼荆针。 笑死,一個胖子當(dāng)著我的面吹牛颁糟,可吹牛的內(nèi)容都是我干的航背。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼棱貌,長吁一口氣:“原來是場噩夢啊……” “哼玖媚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起婚脱,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤今魔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后障贸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體错森,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年篮洁,在試婚紗的時候發(fā)現(xiàn)自己被綠了涩维。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡袁波,死狀恐怖瓦阐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情篷牌,我是刑警寧澤睡蟋,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站枷颊,受9級特大地震影響薄湿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜偷卧,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吆倦。 院中可真熱鬧听诸,春花似錦、人聲如沸蚕泽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至仔蝌,卻和暖如春泛领,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背敛惊。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工渊鞋, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瞧挤。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓锡宋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親特恬。 傳聞我的和親對象是個殘疾皇子执俩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,846評論 25 707
  • 一. Fragment簡介 我們都知道,Android上的界面展示都是通過Activity實現(xiàn)的癌刽,Activity...
    alsheng閱讀 2,416評論 0 8
  • 一役首、使用詳解 (1)Handler使用 (2)Handler構(gòu)造方法 Handler():構(gòu)造函數(shù)將通過調(diào)用Loo...
    kjy_112233閱讀 664評論 0 0
  • 曼德拉: 如果天空是黑暗的, 那就摸黑生存显拜; 如果發(fā)出聲音是危險的衡奥, 那就保持沉默; 如果自覺無力發(fā)光的讼油, 那就蜷...
    萬事從容閱讀 1,103評論 0 0
  • 玩ps已經(jīng)有些年頭了杰赛,今天我想說說對于學(xué)習(xí)PS的一些感受,首先我覺得PS真的是一個非常其妙的東西矮台,它可以改變你...
    山村漁夫閱讀 1,694評論 0 1