LayoutInflater.inflate方法浅析
2015-11-30 13:19
441 查看
在Android中,LayoutInflater.inflate()方法一般用于加载布局,相信很多朋友对它已经很熟悉了,但inflate()方法是如何实现的可能有些朋友还不是很清楚,inflater()在使用的时候都有哪些注意事项呢?让我们来简单分析下:
首先不妨来看看Fragment的onCreateView方法,它包含了几个参数,一个LayoutInflater,一个ViewGroup,和一个传递数据用的Bundle。我们可以这样使用inflate方法来为Fragment加载一个布局:
这里的inflate(int resource, ViewGroup root, boolean attachToRoot)方法包含了三个参数:resource代表要加载布局的id,root代表inflate对象所依托的父容器,boolean attachToRoot表示是否需要将inflate的View依托到root中。inflate还有两个参数的方法,inflate(int resource, ViewGroup root) 其实也是调用了上面的方法。源码如下:
可见,inflater首先会将resource所在的XML进行解析,接下来会调用如下方法:
这里只列出了inflate的核心部分,解析xml的代码没有列出。从代码中可以看出,关于root和attachToRoot两个参数存在着如下逻辑:
1、root为空,attachToRoot失去意义,无论它是true还是false,都不会将layout加载到root中,只是返回createViewFromTag()方法所加载的view;
2、如果root不为空,attachToRoot设为true,则会给layout指定一个父布局root(root.addView(temp, params))。
3、如果root不为空,attachToRoot设为false,则只是将root的布局参数设置给要加载的layout(temp.setLayoutParams(params)),这也是最常用的一种情况。当该layout被添加到父view当中时,这些layout属性会自动生效。
通常,我们只需得到一个布局的View,此时,将root参数置空即可,然后可以将该View添加到我们自己的布局中,通过我们自己的布局可以为它设置layout参数。而如果我们想使用一个ViewGroup的layout参数,只需将root参数设为该ViewGroup,attatchToRoot设为false即可。如果还想将这个ViewGroup也加载进来,可以将attatchToRoot设置为true。
另外一点,在构建Fragment的时候,一定要将attachToRoot设置为false,否则,fragment会将root也就是构建Fragment的Activity的布局也加载进来,这个布局又会加载fragment,造成死循环,出现stackOverFlow异常。
首先不妨来看看Fragment的onCreateView方法,它包含了几个参数,一个LayoutInflater,一个ViewGroup,和一个传递数据用的Bundle。我们可以这样使用inflate方法来为Fragment加载一个布局:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.mylayout,container,false); return rootView; }
这里的inflate(int resource, ViewGroup root, boolean attachToRoot)方法包含了三个参数:resource代表要加载布局的id,root代表inflate对象所依托的父容器,boolean attachToRoot表示是否需要将inflate的View依托到root中。inflate还有两个参数的方法,inflate(int resource, ViewGroup root) 其实也是调用了上面的方法。源码如下:
public View inflate(int resource, ViewGroup root, boolean attachToRoot) { final Resources res = getContext().getResources(); final XmlResourceParser parser = res.getLayout(resource); try { return inflate(parser, root, attachToRoot); } finally { parser.close(); } }
可见,inflater首先会将resource所在的XML进行解析,接下来会调用如下方法:
public View inflate(XmlPullParser parse, ViewGroup root, boolean attachToRoot) { ... final View temp = createViewFromTag(root, name, attrs, false); ViewGroup.LayoutParams params = null; if (root 4000 != null) { // 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) temp.setLayoutParams(params); } } // Inflate all children under temp rInflate(parser, temp, attrs, true, true); // We are supposed to attach all the views we found (int temp) // to root. Do that now. if (root != null && attachToRoot) { root.addView(temp, params); } // Decide whether to return the root that was passed in or the // top view found in xml. if (root == null || !attachToRoot) { result = temp; } ... return result; }
这里只列出了inflate的核心部分,解析xml的代码没有列出。从代码中可以看出,关于root和attachToRoot两个参数存在着如下逻辑:
1、root为空,attachToRoot失去意义,无论它是true还是false,都不会将layout加载到root中,只是返回createViewFromTag()方法所加载的view;
2、如果root不为空,attachToRoot设为true,则会给layout指定一个父布局root(root.addView(temp, params))。
3、如果root不为空,attachToRoot设为false,则只是将root的布局参数设置给要加载的layout(temp.setLayoutParams(params)),这也是最常用的一种情况。当该layout被添加到父view当中时,这些layout属性会自动生效。
通常,我们只需得到一个布局的View,此时,将root参数置空即可,然后可以将该View添加到我们自己的布局中,通过我们自己的布局可以为它设置layout参数。而如果我们想使用一个ViewGroup的layout参数,只需将root参数设为该ViewGroup,attatchToRoot设为false即可。如果还想将这个ViewGroup也加载进来,可以将attatchToRoot设置为true。
另外一点,在构建Fragment的时候,一定要将attachToRoot设置为false,否则,fragment会将root也就是构建Fragment的Activity的布局也加载进来,这个布局又会加载fragment,造成死循环,出现stackOverFlow异常。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories