码迷,mamicode.com
首页 > 移动开发 > 详细

[Android]Fragment源码分析(一) 构造

时间:2014-08-01 23:14:01      阅读:289      评论:0      收藏:0      [点我收藏+]

标签:android   viewpager   fragment   

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!
 <pre name="code" class="java">       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的状态的时候我会回头来解释这个逻辑。




[Android]Fragment源码分析(一) 构造,布布扣,bubuko.com

[Android]Fragment源码分析(一) 构造

标签:android   viewpager   fragment   

原文地址:http://blog.csdn.net/hello__zero/article/details/38341795

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!