安卓開發之Fragment的使用與通訊

cxmscb發表於2016-07-04

一、什麼是Fragment

  1. 在應用程式中, 一個Fragment應該是一個模組化可重用的“片段Activity”。其行為與Activity很相似,有自己對應的View,有自己的生命週期(受宿主Activity的生命週期影響)。

  2. 可以在多個Activity中包括同一個Fragment,也可以在一個Activity中包含多個Fragment。

  3. 更為重要的是,可以動態的給Activity新增、替換和移除某個Fragment。

  4. 當Activity介面中有Fragment,那麼該Activity需要繼承FragmentActivity。

  5. 導包:android-support-v4.jar ,可相容低版本的安卓系統。

  6. 每個Fragment本質上都會生成一個FrameLayout根佈局。(與Activity類似)

二、Fragment的載入方式

1. 定義Fragment的子類,並載入一個佈局檔案


public class MyFragment1 extends Fragment{

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        //載入檢視:將layout佈局檔案轉換成View物件

        /**inflater.inflate 引數說明
         * resource:Fragment需要載入的佈局檔案
         * root:載入layout的父ViewGroup
         * attactToRoot:false,不返回父ViewGroup
         */
        View view = inflater.inflate(R.layout.fragment, container, false);

        // 根據id獲取佈局裡面的TextView
        TextView text=(TextView) view.findViewById(R.id.text);
        text.setText("動態載入Fragment");

        //返回檢視
        return view;

    }

}

2. 靜態載入

直接在在Activity對應的XML佈局檔案中新增上fragment標籤

<fragment android:name="com.example.MyFragment1"
           android:id="@+id/myfragment1"
           android:tag="myfragment1"
           android:layout_width="match_parent"
           android:layout_height="wrap_content" />
  1. android:name為對應的Fragment的類名

  2. android:id/tag可唯一標識Fragment。
    (每個fragment需要一個唯一的標識,當activity重新啟動時,系統需要使用這個唯一的標識去恢復這個fragment。)

  3. 宿主Activity和Fragment共享控制元件,可以在Activity中直接findViewById來查詢已新增的Fragment中的控制元件。

3. 動態載入

在你的activity中管理fragment ,你需要使用 FragmentManager 來使用開始事務。

//建立Fragment物件
MyFragment1 myfragment1 = new Fragment1(); 

//通過事務來動態處理Fragment
FragmentManager fm = this.getFragmentManager();  
FragmentTransaction transaction = fm.beginTransaction();  

//新增Fragment物件。tag為該該物件的標識。
transaction.add(R.id.id_content, myfragment1,"tag");  

//add:將當前Fragment的佈局新增id_content的佈局中
//replace(R.id...,fragment):將當前Fragment的佈局替代id_content的控制元件
//remove():將當前Fragment的佈局從id_content的佈局移除中
//hide()  show()   attach()  detach()

//transaction.addToBackStack("tag");
transaction.commit();  //提交事務

BackStack —- Fragment回溯棧

  1. 如果你的多個改變放在同一個事務中,想要記錄之前的Fragment,那就在commit() 之前呼叫了addToBackStack(String tag)方法(引數’tag’將作為本次加入BackStack的Transaction的標誌),此時所有的改變都會作為一個事務增加到返回棧當中去。當按返回鍵之後,改變會回滾到上一次保留的狀態。

  2. 可以呼叫popBackStack函式將Fragment彈出桟。

三、Fragment的生命週期

Fragment的生命週期和宿主Activity有關,可以通過Activity的生命週期來理解Fragment的生命週期。

這裡寫圖片描述

四、宿主Activity向Fragment通訊

//Activity中

MyFragment5 fragment5 = new MyFragment5();
Bundle bundle = new Bundle();
bundle.putString("name", "data");
//使用Fragment的setArguments方法
fragment5.setArguments(bundle);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
beginTransaction.add(R.id.layout, fragment5, "fragment5");
beginTransaction.commit();

當Activity中沒有任何Fragment的引用時(例如靜態載入Fragment),可以通過getFragmentManager.findFragmentByTag()或者findFragmentById()獲得任何Fragment例項,然後進行操作。(每個Fragment都有一個唯一的tag或者id)


public class MyFragment5 extends Fragment{


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View view = inflater.inflate(R.layout.fragment2, container, false);

        //在Fragment中接收。接收時可判斷是否為空。
        String text=getArguments().get("name");

        return view;
    }
}

五、Fragment向宿主Activity通訊

Fragment向宿主Activity通訊:可以在Fragment中宣告一個介面,在介面裡定義帶引數(引數即我們要傳過去的資料)的抽象方法,為activity建立一個回撥事件。
在一個fragment中定義一個回撥介面,然後activity實現此介面.當這個activity接收到這個介面的回撥時,如果需要的話,你還可以共享你的資料與其他的fragment。

public class MyFragment5 extends Fragment{

    private String code="Hi,Activity!";

    public MyListener listener;
    public interface MyListener
    {
        public void hi(String code);
    }

    @Override
    public void onAttach(Activity activity) {
        // TODO Auto-generated method stub  
        listener=(MyListener) activity;
        super.onAttach(activity);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View view = inflater.inflate(R.layout.fragment2, container, false);

        listener.hi(code); //讓Activity呼叫其自身方法
        return view;
    }
}

public class MainActivity extends Activity implements MyFragment5.MyListener {



    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main4);

    }

    @Override
    public void hi(String code) {

        Toast.makeText(MainActivity.this, "已成功接收到" + code + ",客氣了!",
        Toast.LENGTH_SHORT).show();
    }

}

相關文章