Android學習(五)——Fragment

Fragment

fragment本來設計的初中是爲了適應大屏幕的平板電腦,現在我們普通的手機開發也會加入這個Fragment,我們可以把他理解爲小型的Activity,但是他還是必須嵌套在Activity裏使用的,所以我們可以按照直譯去理解他——Activity的一個“碎片”。雖然fragment有自己的生命週期,但是還是會受到宿主Activity的影響。

生命週期

這裏寫圖片描述

FragmentManager

這裏說一下,fragment目前有兩種,一個是v4包的fragment,還一個是原生的fragment,所以fragmentManager的獲取方式也有兩種:

  • getSupportFragmentManager() 用於v4包獲取fragmentManager
  • getFragmentManager() 用於app包的Fragment獲取Fragmentmanager

FragmentManager用來處理fragment的一部分操作

  • 使用findFragmentById()或findFragmentByTag()方法,得到Activity中存在的fragment,也可判斷Ativity中發fragment是否爲空。
  • popBackStack():將back stack中最後一次的fragment轉換彈出。如果沒有可以出棧的東西,返回false。

FragmentTransaction

這個是具體處理Fragment事務的類,可以執行一些操作例如對fragment增加,刪除,替換,隱藏的這些操作

FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();

transaction.add(R.id.fragment_container, newFragment);//添加一個fragment
transaction.replace(R.id.fragment_container, new2Fragment);//替換一個fragment
transaction.hide(newFragment);//隱藏一個fragment
transaction.remove(newFragment);//刪除一個fragment
transaction.addToBackStack(null);加入BACK棧
transaction.commit();//提交事務操作

關於commit方法

  • 調用commit方法並不是立即執行transaction中包含的改變動作,commit方法吧transaction加入activity的UI線程隊列中
  • 你只能在activity儲存它的狀態之前調用commit,如果在儲存狀態之後調用將會拋出異常(儲存狀態:也就是用戶離開activity,saveInstanceStates的時候)

關於add和replace的性能

fragment替換的方式有兩種:
1. add進來 然後 hide調再add一個新的fragment,當想切回之前的fragment的時候hide掉新的fragment,show舊的fragment。
2. add進來,然後replace成新的fragment,當想切回去的時候繼續repalce成舊的

之前找到一個博客顯示了這兩種方式的性能比:
add方式
這裏寫圖片描述

replace方式
這裏寫圖片描述

所以 如果想提升性能的話 儘量使用add方式添加fragment

封裝一個添加和切換的方法:

     /**
     * 添加/或展示一個fragment
     * @param fragment 想要添加/展示的fragment
     * @param id 佔位佈局的ID
     * @param tag 打一個T啊,需要用這個Tag去搜索是否存在這個fragment
     */
    private <T extends Fragment> void addNewFragment( T fragment, int id, String tag) {

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

        //優先檢查,fragment是否存在,避免重疊
        T tempFragment = (T)fragmentManager.findFragmentByTag(tag);

        if (tempFragment != null) {
            fragment = tempFragment;
        }

        if (fragment.isAdded()) {
            addOrShow(fragmentTransaction, fragment, id, tag);
        } else {
            if (currentFragment != null && currentFragment.isAdded()) {
                fragmentTransaction.hide(currentFragment).add(id, fragment, tag).commit();
            } else {
                fragmentTransaction.add(id, fragment, tag).commit();
            }
            currentFragment = fragment;
        }
    }

    /**
     * 添加/展示fragment方法
     * @param transaction fragment處理事務
     * @param fragment 想要添加/展示的fragment
     * @param id 佔位佈局的ID
     * @param tag fragment查詢標識
     */
    private <T extends Fragment> void addOrShow(FragmentTransaction transaction, T fragment, int id, String tag) {
        if (currentFragment == fragment)
            return;
        if (!fragment.isAdded()) { // 如果當前fragment未被添加,則添加到Fragment管理器中
            transaction.hide(currentFragment).add(id, fragment, tag).commit();
        } else {
            transaction.hide(currentFragment).show(fragment).commit();
        }
        currentFragment.setUserVisibleHint(false);
        currentFragment = fragment;
        currentFragment.setUserVisibleHint(true);
    }

這裏講解一下

首先我們傳進來的是 Fragment的子類 用了個泛型(其實這裏傳一個Fragment也可以,我覺得我好像有點多此一舉)
接下來,看流程:

Created with Raphaël 2.1.0傳入參數通過Tag查找這個fragment存在?fragment = 查出來的是否添加了?添加或者展示isAdded()?add currentFragment = fragment;結束show當前非空且add?隱藏當前fragmentaddyesnoyesnoyesnoyesno

這樣一來,不管你替換什麼fragment,只要調用這個方法,就會使用Add方式替換fragment了(這流程挺簡單的一看就懂,要是看不懂,直接粘代碼簡單粗暴)

結語

其他的我就不多講了,到這裏爲止就可以初步的使用fragment了,至於更深層的東西希望大家多思考,編程嘛,水深得很,總有更屌的方法,更靈活的方法,更貼近業務的方法,所以,學無止境

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