Android小知識-Fragment

轉載請標明出處:【顧林海的博客】

前言

今天還是總結下Android中的小知識點Fragment,Fragment使用廣泛,有自己的生命週期(必須依附Activity),動態靈活的加載到Activity中去,Android 3.0 引入,常用模式有Fragment+ViewPager。


Fragment加載到Activity的兩種方式

  • 添加Fragment到Activity的佈局文件當中。
  • 在Activity的代碼中動態添加Fragment。

第一種方式雖然簡單但靈活性不夠。添加Fragment到Activity的佈局文件當中,就等同於將Fragment及其視圖與activity的視圖綁定在一起,且在activity的生命週期過程中,無法切換fragment視圖。

第二種方式比較複雜,但也是唯一一種可以在運行時控制fragment的方式(加載、移除、替換)。

第二種方式代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/background">

    <FrameLayout
        android:id="@+id/id_fl_homepage"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/id_bottom_menu" />
</RelativeLayout>
    private static Fragment mContentFragment;

    /**
     * Fragment的切換
     *
     * @param fragment Fragment
     */
    private void switchFragment(Fragment fragment) {
        if (mContentFragment != fragment) {
            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.hide(mContentFragment);
            if (fragment.isAdded()) {
                fragmentTransaction.show(fragment);
            } else {
                fragmentTransaction.add(R.id.id_fl_homepage, fragment);
            }
            fragmentTransaction.commitAllowingStateLoss();
            mContentFragment = fragment;
        }
    }

FragmentPagerAdapter與FragmentStatePagerAdatper區別

FragmentPagerAdapter適用於頁面較少的情況下,FragmentStatePagerAdapter適用於頁面較多的情況下。

查看FragmentStatePagerAdapter源碼:

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        Fragment fragment = (Fragment) object;

        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object
                + " v=" + ((Fragment)object).getView());
        while (mSavedState.size() <= position) {
            mSavedState.add(null);
        }
        mSavedState.set(position, fragment.isAdded()
                ? mFragmentManager.saveFragmentInstanceState(fragment) : null);
        mFragments.set(position, null);
        //真正的釋放了Fragment內存。
        mCurTransaction.remove(fragment);
    }

重點在最後一行,mCurTransaction.remove(fragment);表示釋放了Fragment內存。

再查看FragmentPageAdapter源碼:

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
                + " v=" + ((Fragment)object).getView());
        mCurTransaction.detach((Fragment)object);
    }

同樣看最後一行調用了FragmentTransaction的detach方法,detach方法只是將Fragment UI和Activity UI脫離開,並不會回收內存。

Fragment生命週期

Fragment不是獨立,它依附於Activity,

Fragment與Activity生命週期對比圖:

Fragment之間的通信

  • 在Fragment中調用Activity中的方法: getActivity。
  • 在Activity中調用Fragment中的方法: 接口回調。
  • 在Fragment中調用Fragment中的方法: findFragmentById

Fragment管理器:FragmentManager

FragmentManager方法:replace、add、remove。

replace作用是替換Fragment實例,add作用是添加Fragment實例,remove移除Fragment。

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