Fragment詳解

鴻洋大神

一、Fragment爲什麼會被稱爲第五大組件

一、Fragment爲什麼會被稱爲第五大組件

Fragment的中文含義是碎片,在之前安卓開發是,用戶界面的切換全部使用activity的切換,這就造成了整個應用使用起來速度較慢,而且很佔內存,因爲activity是重量級的組件,在應用程序內部使用很不方便。於是出現了Fragment來解決這樣的問題。Fragment是一種便捷的、輕量級的、基於activity的組件,所謂基於activity,就是必須有activity作爲容器,Fragment纔可以生存。另外,Fragment 可以動態的添加和刪除。所以說Fragment是一種非常方便開發的組件 。

二、Fragment加載到Activity中的兩種方式

1、在Activity佈局文件的內部聲明Fragment。

<fragment
name用於設置Fragment子類的類完整路徑(全類名)
android:name="com.example.news.MyFragment"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />

2、使用FramLayout通過代碼添加要顯示的Fragment

`FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();`

使用FrameLayout的優點:

1、通過在佈局中添加顯示Fragment與通過在代碼中添加顯示Fragment有沒有什麼區別??
通過在佈局中添加fragment標籤顯示的Fragment對象永遠無法被替換以及刪除。

2、在通過代碼添加Fragment的時候,使用FrameLayout與其餘的Layout有什麼區別??有什麼優點??

a.假設Fragment中設置的佈局寬高以及佈局控件中設置的寬高都設置match_parent,添加到FrameLayout中的Fragment可以實現match_parent的特點,但是添加到LinearLayout中的Fragment不行

b. 當通過add方法多次添加要顯示的Fragemnt對象時,如果使用FrameLayout,那麼多個Fragment對象之間是重疊覆蓋效果,而LinearLayout是垂直或者水平排列效果

三、FragmentPagerAdapter和FragmentStatePagerAdapter的區別

主要區別就在與對於fragment是否銷燬:
FragmentPagerAdapter:對於不再需要的fragment,選擇調用detach方法,僅銷燬視圖,並不會銷燬fragment實例。

這裏寫圖片描述

FragmentStatePagerAdapter:會銷燬不再需要的fragment,噹噹前事務提交以後,會徹底的將fragmeng從當前Activity的FragmentManager中移除,state標明,銷燬時,會將其onSaveInstanceState(Bundle outState)中的bundle信息保存下來,當用戶切換回來,可以通過該bundle恢復生成新的fragment,也就是說,你可以在onSaveInstanceState(Bundle outState)方法中保存一些數據,在onCreate中進行恢復創建。
這裏寫圖片描述

如上所說,使用FragmentStatePagerAdapter當然更省內存,但是銷燬新建也是需要時間的。一般情況下,如果你是製作主頁面,就3、4個Tab,那麼可以選擇使用FragmentPagerAdapter,如果你是用於ViewPager展示數量特別多的條目時,那麼建議使用FragmentStatePagerAdapter。

二、Fragment的生命週期

這裏寫圖片描述

Fragment和Activity生命週期的綁定

這裏寫圖片描述

三、Fragment之間的通信

一、在Activity向Fragment中傳值

1、要傳的值 放到Bundle對象裏

2、通過創建傳遞封Fragment 將bundle對象 通過 setArguments()傳遞到fragment

3、Fragment中 通過getArguments() 得到 bundle對象 就能得到裏面的值

二、在Fragment向Activity中傳值

1.在Fragment中寫一個回調接口

2.在activity中實現這個回調接口

3,在Fragment中onAttach 方法中得到activity中實現好的 實例化接口對象

4,用接口的對象 進行傳值

public class Fragmen1 extends Fragment{  
    private Button btn1;  
    private EditText et1;  
    CallBackValue callBackValue;  

    /** 
     * fragment與activity產生關聯是  回調這個方法  
     */  
    @Override  
    public void onAttach(Activity activity) {  
        // TODO Auto-generated method stub  
        super.onAttach(activity);  
        //當前fragment從activity重寫了回調接口  得到接口的實例化對象  
        callBackValue =(CallBackValue) getActivity();  
    }  


    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  
            Bundle savedInstanceState) {  
        // TODO Auto-generated method stub  
        View view = inflater.inflate(R.layout.fragment_layout1, container, false);  
         btn1 = (Button) view.findViewById(R.id.btn1);  
         et1 = (EditText) view.findViewById(R.id.et1);  
         btn1.setOnClickListener(new OnClickListener() {  

            @Override  
            public void onClick(View v) {  
                // TODO Auto-generated method stub  
                String strValue = et1.getText().toString().trim();  
                callBackValue.SendMessageValue(strValue);  

            }  
        });  

        return view;  
    }  
    //定義一個回調接口  
    public interface CallBackValue{  
        public void SendMessageValue(String strValue);  
    }  
}

Activity代碼:

public class MainActivity extends Activity implements CallBackValue{  

    private TextView tv1;  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  

        tv1 = (TextView) findViewById(R.id.tv1);  

        FragmentManager manager = getFragmentManager();  
        FragmentTransaction transaction = manager.beginTransaction();  

        transaction.add(R.id.contents, new Fragmen1());  
        transaction.commit();  

    }  
    //要獲取的值  就是這個參數的值  
    @Override  
    public void SendMessageValue(String strValue) {  
        // TODO Auto-generated method stub  
        tv1.setText(strValue);  
    } 

三、在Fragment向Fragment中傳值

1.在FragmentA中通過接口回調的方式,將數據傳遞給當前FragmentA所在的Activity中

2.在Activity的接口重寫方法中,接收到傳遞過來的數據後,通過BFragment對象調用BFragment對象中的自定義方法,將數據再從頁面傳遞給B對象

四、Fragment的管理器:FragmentManager

1、FragmentManager是抽象類,定義了很多方法。具體的實現,在於它的內部類

public abstract class FragmentManager

2、FragmentManager的操作,大部分都在FragmentManagerImpl中。

final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory

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