第一种:
LayoutInflater layoutInflater = LayoutInflater.from(context);
第二种:
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
从源码中可以看出第一种是第二种的封装简化,便于使用:
public static LayoutInflater from(Context context) {
? ? ? ? LayoutInflater LayoutInflater =
? ? ? ? ? ? ? ? (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
? ? ? ? if (LayoutInflater == null) {
? ? ? ? ? ? throw new AssertionError("LayoutInflater not found.");
? ? ? ? }
? ? ? ? return LayoutInflater;
? ? }
我们通过调用inflate方法便可以完成对布局的加载:
layoutInflater.inflate(resource, root, true);?
LayoutInflater中的inflate方法有若干种重载方式,最终都调用了如下代码:
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {
? ? ? ? synchronized (mConstructorArgs) {
? ? ? ? ? ? //获取xml中属性信息
? ? ? ? ? ? final AttributeSet attrs = Xml.asAttributeSet(parser);
? ? ? ? ? ? Context lastContext = (Context)mConstructorArgs[0];
? ? ? ? ? ? mConstructorArgs[0] = mContext;
? ? ? ? ? ? View result = root;
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? // 查找根节点.
? ? ? ? ? ? ? ? int type;
? ? ? ? ? ? ? ? while ((type = parser.next()) != XmlPullParser.START_TAG &&
? ? ? ? ? ? ? ? ? ? ? ? type != XmlPullParser.END_DOCUMENT) {
? ? ? ? ? ? ? ? ? ? // Empty
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? if (type != XmlPullParser.START_TAG) {
? ? ? ? ? ? ? ? ? ? throw new InflateException(parser.getPositionDescription()
? ? ? ? ? ? ? ? ? ? ? ? ? ? + ": No start tag found!");
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? //获取根节点名称
? ? ? ? ? ? ? ? final String name = parser.getName();
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? if (DEBUG) {
? ? ? ? ? ? ? ? ? ? System.out.println("**************************");
? ? ? ? ? ? ? ? ? ? System.out.println("Creating root view: "
? ? ? ? ? ? ? ? ? ? ? ? ? ? + name);
? ? ? ? ? ? ? ? ? ? System.out.println("**************************");
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? //如果是merge标签,必须保证父节点不为null且attachToRoot为true
? ? ? ? ? ? ? ? if (TAG_MERGE.equals(name)) {
? ? ? ? ? ? ? ? ? ? if (root == null || !attachToRoot) {
? ? ? ? ? ? ? ? ? ? ? ? throw new InflateException(" can be used only with a valid "
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? + "ViewGroup root and attachToRoot=true");
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? rInflate(parser, root, attrs, false);
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? //代表布局文件中根节点的view
? ? ? ? ? ? ? ? ? ? View temp;
? ? ? ? ? ? ? ? ? ? if (TAG_1995.equals(name)) {
? ? ? ? ? ? ? ? ? ? ? ? temp = new BlinkLayout(mContext, attrs);
? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? //利用反射,通过root名称创建view
? ? ? ? ? ? ? ? ? ? ? ? temp = createViewFromTag(root, name, attrs);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ViewGroup.LayoutParams params = null;
? ? ? ? ? ? ? ? ? ? if (root != null) {
? ? ? ? ? ? ? ? ? ? ? ? if (DEBUG) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println("Creating params from root: " +
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? root);
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? // Create layout params that match root, if supplied
? ? ? ? ? ? ? ? ? ? ? ? //当提供了父容器时,由父容器根据属性值创建布局参数
? ? ? ? ? ? ? ? ? ? ? ? params = root.generateLayoutParams(attrs);
? ? ? ? ? ? ? ? ? ? ? ? if (!attachToRoot) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? // Set the layout params for temp if we are not
? ? ? ? ? ? ? ? ? ? ? ? ? ? // attaching. (If we are, we use addView, below)
? ? ? ? ? ? ? ? ? ? ? ? ? ? //当不把当前view附加到父容器中,则设置获取到的布局参数
? ? ? ? ? ? ? ? ? ? ? ? ? //否则使用下面的addView方法设置
? ? ? ? ? ? ? ? ? ? ? ? ? ? temp.setLayoutParams(params);
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (DEBUG) {
? ? ? ? ? ? ? ? ? ? ? ? System.out.println("-----> start inflating children");
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? // Inflate all children under temp
? ? ? ? ? ? ? ? ? //递归调用此方法加载子布局
? ? ? ? ? ? ? ? ? ? rInflate(parser, temp, attrs, true);
? ? ? ? ? ? ? ? ? ? if (DEBUG) {
? ? ? ? ? ? ? ? ? ? ? ? System.out.println("-----> done inflating children");
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? // We are supposed to attach all the vie