Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> [Android]Fragment源碼分析(一) 構造

[Android]Fragment源碼分析(一) 構造

編輯:關於Android編程

Fragment是Android3.0之後提供的api,被大家廣泛所熟知的主要原因還是因為隨即附帶的ViewPager控件。雖然我並不喜歡用它,但是它確實是一個相對不錯的控件。還是我的一貫作風,我將從源碼上向大家展示什麼是Fragment。我們先寫一個簡單的代碼對Fragment有個直觀的認識:(為了保證我們方便調試,我們可以直接使用V4提供的源碼包)

FragmentTransaction t = getSupportFragmentManager().beginTransaction();
        t.add(android.R.id.content, new TestFragment1());
        t.commitAllowingStateLoss();

通過這些代碼,我們就可以生成一個Fragment,並且我們能在屏幕上直觀的看到這個Fragment所要說明的界面。那麼一個Fragment是否就是一個控件,或者是一個window?或者是視圖的一部分?當然不是。我們來看Fragment的繼承樹:

public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener

你根本看不到任何View的影子。我在加入M公司之前參加過不少公司的面試,面試官總是斬釘截鐵的告訴我Fragment就是一個片段就是用來顯示大屏幕下的一部分控件。他們這麼堅定的問題在於被Fragment所帶來的ViewPager這種好用的控件和可以在xml配置這個功能所蠱惑,他們缺乏對LayoutInflater源碼的認識。實際上,這點,你不得不對Android這部分代碼的開發者致敬,因為他讓代碼有了無限擴展的可能。

我們先來看下FragmentActivity:

android.support.v4.app.FragmentActivity
@Override
    protected void onCreate(Bundle savedInstanceState) {
        mFragments.attachActivity(this, mContainer, null);
        // Old versions of the platform didn't do this!
 
       if (getLayoutInflater().getFactory() == null) {
            getLayoutInflater().setFactory(this);
        }
        


我們知道Activity才是Fragment的根,Fragment作為片段是相對Activity而言,Activity對於Fragment來說本質上是個控制器,用於分發不同的狀態和業務。在onCreate的前半部分,有一個很重要的設置:

       if (getLayoutInflater().getFactory() == null) {
            getLayoutInflater().setFactory(this);
        }
        

這個是用來干嘛的呢?~實際上,你如果了解一點LayoutInflater的源碼其實並不會感到陌生,因為這個接口是為了構造你的View而存在。這就是偉大的Androidsdk開發者給你提供的擴展機會,不論你配置的東西是否繼承於View,只要你實現了這個接口,你就可以按照既定的規則構造出View。這個接口的實現方法在:

 @Override
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        if (!"fragment".equals(name)) {
            return super.onCreateView(name, context, attrs);
        }
        。。。

我們先取前半部分代碼,我們很清楚的看出,實際上fragment標簽是被FragmentActivity特殊處理了。不知道你們是否理解了,如果不特殊處理,那麼交給默認邏輯處理的話,你的對象由於不繼承View一定會導致程序崩潰。那麼我們接著往下看:

if (fragment == null) {
            fragment = Fragment.instantiate(this, fname);
            fragment.mFromLayout = true;
            fragment.mFragmentId = id != 0 ? id : containerId;
            fragment.mContainerId = containerId;
            fragment.mTag = tag;
            fragment.mInLayout = true;
            fragment.mFragmentManager = mFragments;
            fragment.onInflate(this, attrs, fragment.mSavedFragmentState);
            mFragments.addFragment(fragment, true);

        }
可以看出fragment的生成是通過Fragment的靜態工廠方法幫你生成。而且生成之後將納入mFragments的管理。那麼什麼是mFragments?實際上mFragments是FragmentManager對象,這是整個Framgent管理中非常重要的對象。但是,我們還是沒有看到View的影子,不要著急,我們接著往下讀:

if (fragment.mView == null) {
            throw new IllegalStateException("Fragment " + fname
                    + " did not create a view.");
        }
        if (id != 0) {
            fragment.mView.setId(id);
        }
        if (fragment.mView.getTag() == null) {
            fragment.mView.setTag(tag);
        }
        return fragment.mView;
發現了麼?實際上,最終並不返回Fragment本身,而是返回Fragment的成員mView。但是我們並沒有看到對這個成員的附值呀?實際上,在mFragments將Fragment add之後,已經對View進行賦值。不過我這裡先賣個關子,下一章我們談到Fragment的狀態的時候我會回頭來解釋這個邏輯。




  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved