Android中LayoutInflater赏析

Android中,为了载入某个布局文件,可以利用LayoutInflator类中的inflator方法,得到View实例。

值得注意的是,除了通常使用的inflator(int resource)这个重载,LayoutInflator也支持通过XmlPullParser来获取外部资源,如inflate(XmlPullParser parser, ViewGroup root),而之前我在没有查阅官方Reference时仅凭借对其他项目源码的实例阅读,就断定不能简单地通过android自身类库来调用外部布局文件,真可谓坐井观天。

AndroidDraw是界面生成工具Droiddraw的子项目,负责Layout Resource XML在客户端的解析生效,实现了类似于LayoutInflator的功能。它使用了辅助栈来还原UI树,并通过XmlPullParser的事件来解析整个XML。源码详见这里

Android源码可以通过SDK Manager下载得到,在android-sdk\sources\android-APILevel\文件夹中。为了了解LayoutInflater的实现,自然寻找目录下LayoutInflater.java文件。

在LayoutInflator中,我没有按照method调用的顺序去阅读,而是下意识匆忙寻找onCreateView,该方法是Factory类的方法,但是在Android源码中并不存在Factory类!原来,Factory是接口- -

需要注意两个方法:

/**
* Recursive method used to descend down the xml hierarchy and instantiate views, instantiate their children, and then call onFinishInflate().
*/
void rInflate(XmlPullParser parser, View parent, final AttributeSet attrs, boolean finishInflate) throws XmlPullParserException, IOException

/**
* Low-level function for instantiating a view by name. This attempts to instantiate a view class of the given <var>name</var> found in this
* LayoutInflater's ClassLoader.
*/

 

public final View createView(String name, String prefix, AttributeSet attrs) throws ClassNotFoundException, InflateException

注释很详细,rInflate递归地处理XML事件,并调用createView来生成具体的View,如Button等。createView中出现两个局部变量:

        Constructor<? extends View> constructor = sConstructorMap.get(name);
        Class<? extends View> clazz = null;

问号是什么?Constructor关键字又是什么?在去年求职过程中,我才对Java泛型乃至STL有了一定的了解,更不用说Reflection。

Android官方实现与AndroidDraw作者实现区别就在于,Android源码采用了Reflection,避免了过多的条件嵌套:

clazz = mContext.getClassLoader().loadClass(
                        prefix != null ? (prefix + name) : name).asSubclass(View.class);
...
constructor = clazz.getConstructor(mConstructorSignature);
return constructor.newInstance(args);

出于好奇,还给AndroidDraw作者发了邮件,询问为什么要自己重写inflate。

总结:

多读高质量的代码,从中可以学到很多东西,不仅仅是针对一个case的实现,还包括代码组织的思想。

不要坐井观天,你知道的真的太少了,不要学得什么都是半桶水,Java不知Reflection,C#不知Delegate,……

posted on 2012-05-09 13:40  魏梦  阅读(972)  评论(0编辑  收藏  举报

导航