欢迎使用CSDN-markdown编辑器

来源:互联网 发布:平面设计软件有哪些 编辑:程序博客网 时间:2024/06/11 20:23

浅析LayoutInflater

  平时我们我们的布局都是在xml当中来写,在Activity中通常是调用setContentView()方法,而我们做Android开发的对LayoutInflater同样不会陌生。当然setContentView()底层也是通过LayoutInflater来加载布局的。  我们常用的LayoutInflater有三种:      1.LayoutInflater inflater = getLayoutInflater();  //调用Activity的getLayoutInflater()      2.LayoutInflater localinflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);      3.LayoutInflater inflater = LayoutInflater.from(context);  这三种方式其实最终都是调用了Context.getSystemService();

Inflater的重载方法

 public View inflate (int resource, ViewGroup root);   public View inflate (XmlPullParser parser, ViewGroup root); public View inflate (XmlPullParser parser, ViewGroup root, boolean attachToRoot);    public View inflate (int resource, ViewGroup root, boolean attachToRoot); 

其中第二个参数指定了是ViewGroup root,当然我们也可以设置为null


这里我们需要注意一下inflate方法与 findViewById 方法不同

inflate方法是用来找res/layout下的xml布局,并将其实例化findViewById方法是找xml布局中具体的某个控件

回归我们今天的主题 ,LayoutInflater是怎么将一个xml布局具体实例化

无论我们使用的是那个inflate的那个重载方法最终都会来到如下代码:

public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {
synchronized (mConstructorArgs) {
final AttributeSet attrs = Xml.asAttributeSet(parser);
mConstructorArgs[0] = mContext;
View result = root;
try {
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG &&
type != XmlPullParser.END_DOCUMENT) {
}
if (type != XmlPullParser.START_TAG) {
throw new InflateException(parser.getPositionDescription()
+ ": No start tag found!");
}
final String name = parser.getName();
if (TAG_MERGE.equals(name)) {
if (root == null || !attachToRoot) {
throw new InflateException("merge can be used only with a valid "
+ "ViewGroup root and attachToRoot=true");
}
rInflate(parser, root, attrs);
} else {
View temp = createViewFromTag(name, attrs);
ViewGroup.LayoutParams params = null;
if (root != null) {
params = root.generateLayoutParams(attrs);
if (!attachToRoot) {
temp.setLayoutParams(params);
}
}
rInflate(parser, temp, attrs);
if (root != null && attachToRoot) {
root.addView(temp, params);
}
if (root == null || !attachToRoot) {
result = temp;
}
}
} catch (XmlPullParserException e) {
InflateException ex = new InflateException(e.getMessage());
ex.initCause(e);
throw ex;
} catch (IOException e) {
InflateException ex = new InflateException(
parser.getPositionDescription()
+ ": " + e.getMessage());
ex.initCause(e);
throw ex;
}
return result;
}
}


看到这里我们可以很清晰的了解到它其实是通过Android提供的pull解析来解析布局文件的,之后我们会发现它调用了createViewFromTag()方法把节点名和参数传了进去,从这里我们可以了解到它其实是通过节点名来创建View,在createViewFromTag()中有调用了CreateView()方法创建view。之后会调用rInflate()方法来循环遍历这个根布局下的子元素

这个就是LayoutInflater将一个xml布局具体实例化的过程。

初写博客,不喜勿喷。欢迎大家一起交流,学习,共同进步。—— 一只刚出炉的Android小白