2013年4月27日 星期六

Android - Fragment

        在Android 3.0之後,設計上發生了一些變革,最重要的莫過於Fragment與Action Bar,除了可以讓應用程式設計上更有彈性,使用更優雅之外,更可以重複性的使用這些Fragment,並且在Support Library的支援下,使用Fragment來設計跨版本的應用程式是個不錯的選擇。
Fragment是擁有部份功能的Activity,Fragment必須使用在Activity裡,也直接受到Activity的影響,例如:如果Activity Pause或Destroy,則在該Activity裡的Fragment也會一併Pause或Destroy。

        Fragment的設計應該視為一個可重用的Activity模組,因為Fragment會有自己的Layout及Life-cycle,並且Fragment是可以使用到不同的Activity裡進行重用,所以在設計Fragment時,不應該在Fragment裡再呼叫其他Fragment,例如:在Tablet時,因為有比較大的螢幕,所以使用單獨的兩個Fragment包在同一個Activity裡,而在Handset時,則不必再重寫Fragment,直接將不同的Fragment運用在不同的Activity裡;並且當使用FragmentTransaction添加或取代一個Fragment到一個Activity的Layout時,其Fragment的Layout是添加到Activity的ViewGroup內。



Fragment生命週期

       如果要建立一個Fragment,則必須使用繼承自Fragment的子類別,例如:ListFragment、DialogFragment、PreferenceFragment等。下圖為Fragment的生命週期,紅色框代表必須實作的事件,而onCreateView會在要呈現該Fragment畫面時就會執行,所以onCreateView所傳回的是View,並且帶入參數就有LayoutInflater,可以幫助Layout轉化成View加入到Activity的ViewGroup中,如果使用的是ListFragment,則預設該View就為ListView;如果一個Activity裡配置一個Fragment,則container參數會是null,也就是Fragment的Layout並沒有跟Activity的Layout綁在一起,如果是使用FragmentTransaction加入或取代Fragment,則container參數會是Activity的ViewGroup。
例:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.example_fragment, container, false);
    }


        至於其他的事件,例如:onCreate()、onStart()、onResume()、onPause()、onStop()、onDestroy(),基本上都與Activity所對應的事件相似。除了直接在Layout裡指定Fragment之外,如果要在程式端動態增加、取代、刪除Fragment,可以使用FragmentTransaction來達成,例如:

FragmentTransaction ft = getFragmentManager().beginTransaction();

//只要是ViewGroup即可,不一定要FrameLayout
ft.replace(R.id.details, details);//進行取代   
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);

//如果有加上這一行會將Fragment加到Back Stack,
//這樣就可以直接使用上一頁鈕回到上一個Fragment的狀態,
//否則按下上一頁就會直接關掉Activity
ft.addToBackStack(null);

//完成Fragment的異動
ft.commit();

commit必須在Activity Save State
(也就是 Another activity comes into the foreground)之前執行,否則會拋錯,
要不就要執行commitAllowingStateLoss()。


轉貼請註明出處,最好直接使用聯結轉貼!Thanks~
作者: Samuel - 林靖傑
日期:2013/04/27