1. 程式人生 > >切換Fragment避免重複載入

切換Fragment避免重複載入

現在市面上很多手機應用都會有一個非常類似的功能,就是螢幕下方有一行Tab標籤選項,點選不同的標籤就可以切換到不同的介面:


這個在以前是用ActivityGroup(年代太久遠了,那時候俺還木有畢業呢0.0),因為Fragment的種種優勢和其靈活性,現在官方推薦的替代方法是用Fragment。

使用Fragment的話,我之前是先通過getSupportFragmentManager(),再beginTransaction()開啟事務,FragmentTransaction中有add(),replace(),remove()三個方法,我之前是用replace方法每次替換掉之前的Fragment,但是我們會發現,使用replace()時,每次切換,Fragment都會重新建立,這樣就比較不好了。從網上搜索發現可以通過show和hide方法避免重複載入(借鑑了郭霖大神的思路,但是他的方式在我的app裡會出現重影)。So我換了一種實現方式。當然本質沒有區別,還是通過一次將所有的Fragment新增到一個集合裡,再通過隱藏和顯示完成的。

佈局檔案還是RadioGroup巢狀RadioButton,程式碼隨便看看就好啦

<LinearLayout
    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"
    android:orientation="vertical"
    tools:context="com.example.v_lzhiy.tablayout.HideFragmentActivity">
        <FrameLayout
            android:id="@+id/fl_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    <RadioGroup
        android:id="@+id/radioGroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#f9f9f9"
        android:gravity="center_horizontal"
        android:orientation="horizontal"
        android:padding="5dp"
        >
            <RadioButton
                android:id="@+id/pager1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:background="@android:color/transparent"
                android:button="@android:color/transparent"
                android:drawableTop="@drawable/rb_me_selector"
                android:textSize="18sp"
                android:textColor="@drawable/bottom_radiobutton_selector"
                android:drawablePadding="1dp"
                android:gravity="center"
                android:text="Home"/>
        <RadioButton
            android:id="@+id/pager2"
            style="@style/BottomRadioButton"
            android:text="探索"
            android:drawableTop="@drawable/rb_me_selector"/>
        <RadioButton
            android:id="@+id/pager3"
            style="@style/BottomRadioButton"
            android:text="我"
            android:drawableTop="@drawable/rb_me_selector"/>
    </RadioGroup>
</LinearLayout>
FrameLayout作為容器裝載Fragment,這裡簡單做三個Fragment就好了,就不放程式碼了。然後該初始化的初始化,該findViewById的findViewById,然後也是開啟個事務,把我們的幾個Fragment新增到一個ArrayList中。PagerOne,PagerTwo,PagerThree就是我們說的三個Fragment。
fragmentManager = getSupportFragmentManager();
        fragmentTransaction = fragmentManager.beginTransaction();
        fragments = new ArrayList<>();
        pagerOne = new PagerOne();
        pagerTwo = new PagerTwo();
        pagerThree = new PagerThree();
        fragments.add(pagerOne);
        fragments.add(pagerTwo);
        fragments.add(pagerThree);

        fragmentTransaction.add(R.id.fl_container,pagerOne);
        fragmentTransaction.add(R.id.fl_container,pagerTwo);
        fragmentTransaction.add(R.id.fl_container,pagerThree);

再把三個Fragment新增到FragmentTransaction中,是add不是replace哦。這樣,我們就可以通過我們選擇不同的Radiobutton通過顯示與隱藏的方式切換Fragment了,但是在這之前,我們還要做一件事,三個Fragment都新增進去了,會出現重影……需要我們手動設定進入app時要顯示哪一頁,其餘的隱藏。我這裡是顯示第一頁:

radioGroup.check(R.id.pager1);
        fragmentTransaction.show(pagerOne).hide(pagerTwo).hide(pagerThree);
        fragmentTransaction.commit();
這樣就顯示了第一頁,隱藏了其餘兩頁。當我們切換RadioButton時,再顯示該顯示的隱藏其餘的,switchFragment(int index)就是顯示與隱藏的控制程式碼。
 radioGroup.setOnCheckedChangeListener(new NestRadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(NestRadioGroup group, int checkedId) {
                switch(checkedId){
                    case R.id.pager1:
                        switchFragment(0);
                        break;
                    case R.id.pager2:
                        switchFragment(1);
                        break;
                    case R.id.pager3:
                        switchFragment(2);
                        break;
                }
            }
        });
    }

    /**
     * 選擇隱藏與顯示的Fragment
     * @param index 顯示的Frgament的角標
     */
    private void switchFragment(int index){
        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        for(int i = 0; i < fragments.size(); i++){
            if (index == i){
                fragmentTransaction.show(fragments.get(index));
            }else {
                fragmentTransaction.hide(fragments.get(i));
            }
        }
        fragmentTransaction.commit();
    }

這樣就可以避免每次切換都重新建立Fragment了,很簡單吧,但是還有個問題,有時候我們切換的時候需要處理一些事情,比如剛開始是未登入狀態,現在登入了,切換頁面時要更新一些資料,那怎麼辦呢?Fragment裡有個onHiddenChanged方法,是專門用來處理Fragment顯示與隱藏的事件的。
@Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (hidden){
            //隱藏
        }else {
            //顯示,更新資料
        }
    }

恩,這樣就沒毛病了。