關於Fragment的方方面面

簡介

    Fragment相當於是一種特殊的Activity,它需要被嵌套到Activity上面才能起作用,那麼對於大屏設備(如:平板)就就可以考慮在一個Activity上面放置多個Fragment,這樣可以充分利用屏幕面積,而且也可以更方便用戶進行交互操作,當然在手機上面也可以方便的使用它,有了Fragment,我們的APP可以針對平板或是手機做不同的適配。Fragment是在Android3.0(API level 11)版本引入的,如果你使用的是之前的系統,需要先導入android-support-v4的jar包。 

 先看下Fragment的生命週期吧:


 可以看出跟Activity很像,只是多了幾個方法,單獨說明一下:

onAttach()
當fragment被綁定到activity時被調用
onCreateView()
創建fragment佈局時被調用
onActivityCreated()
當activity的onCreate()方法返回時被調用
onDestroyView()
移除fragment的佈局時被調用,跟onCreateView()對應
onDetach()
當fragment跟activity解除關聯時被調用,跟onAttach()對應
 因爲Fragment必須嵌入在Acitivity中使用,所以Fragment的生命週期和它所在的Activity是密切相關的。如果Activity是暫停狀態,其中所有的Fragment都是暫停狀態;如果Activity被銷燬,那麼它其中的所有Fragment都會被銷燬。當Activity在活動狀態時,可以獨立控制Fragment的狀態,比如添加或者移除Fragment。當處理一個fragment事務時, 可以將它添加到activity所管理的back stack -- 每一個activity中的back stack實體都是一個發生過的fragment事務的記錄. back stack允許用戶通過按下 BACK 按鍵從一個fragment回退到上一個fragment。
 
 Fragment加載有兩種方式:靜態和動態。
 先看下靜態加載:
public class MyFragment extends Fragment  
{    
    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  
            Bundle savedInstanceState)  
    {  
        View view = inflater.inflate(R.layout.fragment_one, container, false);          
        return view;  
    }  
}  
在activity_main.xml裏面
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent" >  
  
    <fragment  
        android:id="@+id/id_fragment_title"  
        android:name="com.example.wdong.fragmentdemo.MyFragment"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent" />    
</RelativeLayout>  
然後是動態加載:
在activity_main.xml裏面
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:id="@+id/main_layout"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent" >    
</LinearLayout>  
在MainActivity的onCreate()裏面
MyFragment fragment = new MyFragment();  
getFragmentManager().beginTransaction().replace(R.id.main_layout, fragment).commit();  


在使用Fragment時,常用的api有以下這些:

一、getFragmentManager()獲取FragmentManager。
二、FragmentManager.beginTransaction()開啓一個事務,即FragmentTransaction。
三、FragmentTransaction裏面有一些常用的操作:
1、add() 往Activity中添加一個Fragment
2、remove() 從Activity中移除一個Fragment,如果該Fragment沒有添加到back stack,那麼它將被銷燬
3、replace() 替換一個Fragment,其實就是remove()+add()
4、hide() 隱藏一個Fragment
5、show() 顯示之前隱藏的Fragment
6、detach() 會將view從UI中移除,和remove()不同,此時fragment的狀態依然由FragmentManager維護
7、attach() 重建view視圖,附加到UI上並顯示
8、commit() 提交一個事務

管理Fragment的back stack(回退棧)
有時候,我們可能有這樣的需要:按返回鍵回到上一個Fragment,那麼這時就要用到back stack了。
用法很簡單,比如在FragmentOne裏面有一個按鈕,被按下的話,就執行下面的語句:
FragmentTwo two = new FragmentTwo();  
FragmentManager fm = getFragmentManager();  
FragmentTransaction tx = fm.beginTransaction();  
tx.replace(R.id.id_content, two, "two");
//tx.hide(this);  
//tx.add(R.id.id_content , two, "two");  //這種方式的話FragmentOne的視圖層就不會被銷燬了
tx.addToBackStack(null);  
tx.commit();  
這樣就跳轉到了FragmentTwo,由於我們加了tx.addToBackStack(null),所以再按back鍵,就會回到FragmentOne。
需要說明的是:replace是remove和add的合體,如果不添加事務到回退棧,前一個Fragment實例(FragmentOne)會被銷燬。但這裏我們調用tx.addToBackStack(null);將當前的事務添加到了回退棧,所以FragmentOne實例不會被銷燬,但是視圖層次依然會被銷燬,即會調用onDestoryView和onCreateView。

與Activity通信
通過getActivity()得到Fragment所關聯的Activity,然後就可以獲取Activity(及與Activity有關聯的Fragment)佈局裏面的控件。
View listView = getActivity().findViewById(R.id.list);
同樣地,activity可以通過從FragmentManager獲得一個到Fragment的引用來調用fragment中的方法,使用findFragmentById() 或 findFragmentByTag()。
MyFragment fragment =(MyFragment) getFragmentManager().findFragmentById(R.id.my_fragment);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章