Android笔记之LayoutInflater

来源:互联网 发布:知乎 装修 编辑:程序博客网 时间:2024/05/29 23:24

Android笔记之LayoutInflater

概念

  LayoutInflater类是用于装载xml布局文件, 作用类似于我们常用的findViewById(), 只不过一个是用来找res/layout/下的xml布局文件,并且将实例化成View。 而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。因此一般来说,可分2种情况:

  1. 对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;
  2. 对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。

实例化LayoutInflater

获得 LayoutInflater 实例的三种方式:

    LayoutInflater inflater = getLayoutInflater();//调用Activity的getLayoutInflater()      LayoutInflater inflater = LayoutInflater.from(context);      LayoutInflater inflater =  (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

  查看源代码得知,最终都会调用 (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)。其方法源码如下:

    //Activity.java    public LayoutInflater getLayoutInflater() {        return getWindow().getLayoutInflater();    }    //PhoneWidnow.java    public LayoutInflater getLayoutInflater() {        return mLayoutInflater;    }    public PhoneWindow(Context context) {        super(context);        mLayoutInflater = LayoutInflater.from(context);    }    //LayoutInflater.java    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;    }

装载Xml文件

  使用inflate()方法进行装载文件, 一共有4个方法:

    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)

  下面我们进行源代码分析一下:

    public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {        return inflate(resource, root, root != null);    }    public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {        final Resources res = getContext().getResources();        //XML布局文件解析类        final XmlResourceParser parser = res.getLayout(resource);        try {            return inflate(parser, root, attachToRoot);        } finally {            parser.close();        }    }    public View inflate(XmlPullParser parser, @Nullable ViewGroup root) {        return inflate(parser, root, root != null);    }

  由上面来看,所有的构造方法都会来到inflate (XmlPullParser parser, ViewGroup root, boolean attachToRoot)的方法,下面来看一下该方法主要操作:

    public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {        ...        final AttributeSet attrs = Xml.asAttributeSet(parser);        final View temp = createViewFromTag(root, name, inflaterContext, attrs);        ViewGroup.LayoutParams params = null;        if (root != null) {            // Create layout params that match root, if supplied            //传入了ViewGroup root参数,则根据root布局来得到由layout_width和layout_height组成的LayoutParams            params = root.generateLayoutParams(attrs);            if (!attachToRoot) {                // Set the layout params for temp if we are not, attaching. (If we are, we use addView, below)                //在attachToRoot设置为false的话,就会对我们加载的视图View设置该LayoutParams。                temp.setLayoutParams(params);            }        }        ...        //有root参数 及 attachToRoot为 true则 加载的视图做为子视图添加到root视图中。        if (root != null && attachToRoot) {            root.addView(temp, params);        }        //如何某为空,则直接返回子View的视图        if (root == null || !attachToRoot) {            result = temp;        }    }
0 0