Fragment基本概述


本節引言

好的,在上一章我們把Android的四大元件Activity,Service,BroadCastReceiver,ContentProvider 以及他們之間的連結:Intent,都擼了一遍,而這章節帶給大家的是一個Fragment(碎片)的東西, 本節我們就來介紹這個Fragment的一些基本概念以及用法吧! 官方文件:Fragment


1.基本概念

1)它是什麼鬼,有什麼用?

答案:Fragment是Android3.0後引進的一個新的API,他出現的初衷是為了適應大螢幕的平板電腦, 當然現在他還是平板APP UI設計的寵兒,而且我們一般手機開發也會加入這個Fragment, 我們可以把他當成一個小的Activity,又叫做Activity片段!想想,如果一個很大的介面,我們 就一個佈局,寫起介面來會有多麻煩,而且如果元件多的話是管理起來也很麻煩!而使用Fragment 我們可以把螢幕分成幾塊,然後進行分組,進行一個模組化的管理!從而可以更加方便的在 運行過程中動態地更新Activity的使用者介面!另外Fragment並不能單獨使用,他需要嵌套在Activity 中使用,儘管他擁有自己的生命週期,但是還是會受到宿主Activity的生命週期的影響,例如Activity 被destory銷毀了,他也會跟著銷毀!

下圖是文件中給出的一個Fragment分別對應手機與平板間不同情況的處理圖:

1.png

PS:簡單的新聞瀏覽頁面,使用兩個Fragment分別顯示新聞列表與新聞內容;


2)Fragment的生命週期圖

2.jpg


3)核心要點:

下面說下使用Fragment的一些要點:

  • 3.0版本後引入,即minSdk要大於11
  • Fragment需要嵌套在Activity中使用,當然也可以嵌套到另外一個Fragment中,但這個被嵌套 的Fragment也是需要嵌套在Activity中的,間接地說,Fragment還是需要嵌套在Activity中!! 受寄主Activity的生命週期影響,當然他也有自己的生命週期!另外不建議在Fragment裡面 嵌套Fragment因為嵌套在裡面的Fragment生命週期不可控!!!
  • 官方文檔說創建Fragment時至少需要實現三個方法:onCreate( ),onCreateView( ),OnPause( ); 不過似乎只寫一個onCreateView也是可以的...
  • Fragment的生命週期和Activity有點類似:三種狀態:
    Resumed:在允許中的Fragment可見
           Paused:所在Activity可見,但是得不到焦點
    Stoped: ①呼叫addToBackStack(),Fragment被加入到Bcak棧 ②該Activity轉向後台,或該Fragment被替換/刪除
    ps:停止狀態的fragment仍然活著(所有狀態和成員資訊被系統保持著),然而,它對用戶 不再可見,並且如果activity被幹掉,他也會被幹掉.

4)Fragment的幾個子類別:

ps:很多時候我們都是直接重寫Fragment,inflate載入佈局完成相應業務了,子類用的不多,等需要的 時候在深入研究!

  • 對話框:DialogFragment
  • ##列表:
  • ListFragment
  • 選項設定:
  • PreferenceFragment
  • WebView介面:
  • WebViewFragment

5)是用App包下的Fragment還是v4套件下的:

問題概述:

相信很多朋友在使用Fragment的時候都會遇到下面這種情況:

3.jpg

那我們到底是使用android.app下的Fragment還是用的android.support.v4.app包下 的Fragment呢?

回答:其實都可以,前面說過Fragment是Android 3.0(API 11)後面引進的,那如果開發的app需要 在3.0以下的版本運行呢?例如還有一點點市場份額的2.3!於是乎,v4包就這樣應運而生了, 而最低可以相容到1.6版本!至於使用哪個包看你的需求了,現在3.0下手機市場份額其實已經不多了,隨街都是4.0以上的,6.0十月份都出了,你說呢...所以這個時候,你可以直接使用app包下的Fragment 然後呼叫相關的方法,通常都是不會有什麼問題的;如果你Fragment用了app包的, FragmentManager和FragmentTransaction都需要是app包的!要嘛用全部用app,要嘛全部用v4, 不然可是會報錯的哦!當然如果你要自己的app對於低版本的手機也兼容的話,那麼就可以選擇用v4包!

使用v4套件下Fragment要注意的地方:#

  • ①如果你使用了v4包下的Fragment,那麼所在的那個Activity就要繼承FragmentActivity喔! 案例:今天在xml檔中靜態地載入fragment,然後重寫了Fragment,但是在載入Activity的時候就報錯了, 大概的提示就是Fragment錯誤還是找不到什麼的,name屬性改了幾次還是錯!最後才發現是用了 v4的包的緣故,只需讓自己的Activity改成FragmentActivity即可!
  • #②之前寫了下面這段程式碼,然後報錯:

4.jpg

有點莫名其妙啊,Fragment,FragmentManager,FragmentTransaction都是用的v4包啊, Activity也是繼承FragmentActivity的啊?都改成app包就可以了,但是這不和我們用v4包的 前提衝突了麼?其實也是有解決方法的哈?
答:只需要把getFragmentManager( )改成getSupportFragmentManager( )就可以了


2.建立一個Fragment

1)靜態載入Fragment

#實作流程:

5.png

##範例程式碼:

Step 1:定義Fragment的佈局,就是fragment顯示內容的
Step 2 :自訂一個Fragment類別,需要繼承Fragment或他的子類別,重寫onCreateView()方法 在這個方法中呼叫:inflater.inflate()方法載入Fragment的佈局檔,接著回傳載入的view物件

public class Fragmentone extends Fragment {
    (LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
 se);
        return view;
    }   
}

Step 3:

在需要載入Fragment的Activity對應的版面配置檔案中加入fragment的標籤, 記住,name屬性是全限定類別名稱哦,就是要包含Fragment的套件名稱,如:

<fragment
    android:id="@+id/fragment1"
    android:name="com.jay.example.fragmentdemo.Fragmentone"
    android:layout_width="match_parent"
    and
##

Step 4: Activity在onCreate( )方法中呼叫setContentView()載入佈局檔即可!


##2)動態載入Fragment

#實作流程:

7.png

#範例程式碼:這裡示範的是,當橫豎螢幕切換的時候地切換Fragment:

6.gif

Fragment以及佈局程式碼就不貼出來了,直接貼MainActivity的關鍵程式碼:

public class MainActivity extends Activity {

    @OverLion##    protected void onCreate(Bundle savedInstanceState) {
       activity_main);
        Display dis = getWindowManager() .getDefaultDisplay();
        if(dis.getWidth() > dis.getHeight())
       1();
            getFragmentManager().beginTransaction().replace (R.id.LinearLayout1, f1).commit();
        }
        
         Fragment2 f2 = new Fragment2();
            getFragmentManager().beginTransaction() .replace(R.id.LinearLayout1, f2).commit();
        }
    }   
}





########1

3.Fragment管理與Fragment事務

8.png


#4.Fragment與Activity的互動

9.png

#可能有的朋友不喜歡看圖,接下來用文字介紹下吧:

1)元件取得

Fragment取得Activity中的元件: getActivity(). findViewById(R.id.list);
Activity取得Fragment中的元件(根據id和tag都可以):getFragmentManager.findFragmentByid(R.id.fragment1);


2)資料傳遞

①Activit傳遞資料給Fragment:

在Activity中建立Bundle資料包,呼叫Fragment實例的setArguments (bundle) 從而將Bundle封包傳給Fragment,然後Fragment中呼叫getArguments取得 Bundle物件,然後進行解析就可以了

②Fragment傳遞資料給Activity

在Fragment中定義一個內部回呼介面,再讓包含該Fragment的Activity實作該回呼介面, Fragment就可以透過回呼介面傳資料了,回呼,相信很多人都知道是什麼玩意,但是 寫不出來啊,網上的一百度"fragment傳數據給Activity",全是李剛老師的那個代碼,真心無語 算了,這裡就寫下局部程式碼吧,相信讀者一看就懂的了:

Step 1:定義一個回呼介面:(Fragment中)

/*介面*/  
public interface CallBack{  
    /*定義一個獲取資訊的方法*/  
    1 
##Step 2:介面回呼(Fragment中)

##/*介面回呼*/  public void getData(CallBack callBack){  

  *取得文字方塊的資訊,當然你也可以傳其他類型的參數,看需求咯*/  
    String msg = editText.getText().toString();  
    callBack.getResult(msg); #}

Step 3:使用介面回呼方法讀取資料(Activity中)

/* 使用介面回呼的方法取得資料 */  
#leftFragment.getData(new CallBack() {  
 @Override  
       public void getResult(String result) {       Toast.makeText(MainActivity.this, "-->>" + result, 1) .show();  
            }
        });

摘要總結下方法:#-Famp});
總結下方法:#-Fp中定義抽象方法,你要傳什麼類型的資料參數就設定為什麼型別;
->接著還有寫一個呼叫介面中的抽象方法,把要傳遞的資料傳過去

->

再接著就是Activity了,呼叫Fragment提供的那個方法,然後重寫抽象方法的時候進行數據 的讀取就可以了!!!

③Fragment與Fragment之間的資料互傳


其實這很簡單,找到要接受資料的fragment物件,直接呼叫setArguments傳資料進去就可以了 通常的話是replace時,即fragment跳轉的時候傳資料的,那麼只需要在初始化要跳轉的Fragment 後調用他的setArguments方法傳入數據即可!
如果是兩個Fragment需要即時傳數據,而非跳轉的話,就需要先在Activity獲得f1傳過來的數據, 再傳到f2了,就是以Activity為媒介~

##範例程式碼如下:


FragmentManager fManager = getSupportFragmentManager( );
FragmentTransaction fTransaction = fManager.beginTransaction();
Fragmentthree t1 = new Fragmentthree();
Fragmenttwo t2 = new Fragmentt(woundle);##Fragmenttwo t2 = new Fragmentt(woundle);
Fundle-Fm key",id);
t2.setArguments(bundle); 
fTransaction.add(R.id.fragmentRoot, t2, "~~~");  
fTransaction.addToBackStack(t1);  
fTransaction.commit();
#

5.走一次生命週期圖:

思前想後還是決定要帶大家簡單的走一趟生命週期圖,加深大家對Fragment生命週期的理解:

①Activity載入Fragment的時候,依序呼叫下面的方法:onAttach ->  onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume

②當我們弄出一個懸浮的對話框風格的Activity,或者其他,就是讓Fragment所在的Activity可見,但不獲得焦點onPause

③當對話框關閉,Activity又獲得了焦點:onResume

##④當我們替換Fragment ,並呼叫addToBackStack()將他加入Back棧中

onPause -> onStop -> onDestoryView! ! 注意,此時的Fragment還沒有被銷毀哦!!!

⑤當我們按下鍵盤的回退鍵,Fragment會再次顯示出來:

onCreateView -> onActivityCreated -> onStart -> onResume

#⑥如果我們替換後,在事務commit之前

沒有調用addToBackStack()方法將 Fragment加入back棧中的話;又或者退出了Activity的話,那麼Fragment將會被完全結束, Fragment會進入銷毀狀態onPause -> onStop -> onDestoryView -> onDestory# -> onDetach# -> onDestory# ->

onDetach

本節小結:

本節跟大家講解了以下Fragment一些基本的概念以及簡單的用法,相信大家會慢慢喜歡上 Fragment的,因為篇幅的關係,本節就寫這麼多,下一節我們帶大家來寫一些關於Fragment 的常用實例,敬請期待,謝謝~
######