inflate
2016-03-30 17:07
232 查看
概述
inflate方法在activity的onCreate中,在Listview的Adapter的getView中,在增加view的时候,我们都经常用到inflate方法比如LayoutInflater.from(getContext()).inflate(resId, head)
这个就是把resId指定的layout渲染之后加入到head中。
在使用inflate的使用,我们会经常发现宽高等布局信息失效,这是怎么回事呢?
详解
LayoutInflater的inflate方法主要有2个重载public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) { return inflate(resource, root, root != null); }
两参的本质是调用三参的方法,在看LayoutInflater.from(getContext()).inflate(btnResId, head)
会做哪些事情,首先他根据xml文件用反射创建出View树,这样xml文件对应出了一个View。然后根据View的布局参数和head 的类型创建出LayoutParams,然后我们根据把View添加到head内,添加的参数是LayoutParams。
简单的说,做3件事,创建View,生成LayoutParams,添加View到根布局。
Inflate的核心代码如下所示。
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) { synchronized (mConstructorArgs) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate"); final Context inflaterContext = mContext; final AttributeSet attrs = Xml.asAttributeSet(parser); Context lastContext = (Context) mConstructorArgs[0]; mConstructorArgs[0] = inflaterContext; View result = root; try { // Look for the root node. 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("**************************"); } 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, inflaterContext, attrs, false); } else { // Temp is the root view that was found in the xml final View temp = createViewFromTag(root, name, inflaterContext, 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) temp.setLayoutParams(params); } } if (DEBUG) { System.out.println("-----> start inflating children"); } // Inflate all children under temp against its context. rInflateChildren(parser, temp, attrs, true); if (DEBUG) { System.out.println("-----> done inflating children"); } // 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; } } } catch (XmlPullParserException e) { InflateException ex = new InflateException(e.getMessage()); ex.initCause(e); throw ex; } catch (Exception e) { InflateException ex = new InflateException( parser.getPositionDescription() + ": " + e.getMessage()); ex.initCause(e); throw ex; } finally { // Don't retain static reference on context. mConstructorArgs[0] = lastContext; mConstructorArgs[1] = null; } Trace.traceEnd(Trace.TRACE_TAG_VIEW); return result; } }
分析参数情况
1、三参函数,root为null,此时只做第一件事情,把xml渲染成View,然后返回2、三参函数,root不为null,attachToRoot为true,此时和2参的函数一样,做3件事,返回root的view。
3、三参函数,root不为null,attachToRoot为false,此时把xml渲染成view,生成LayoutParams并设置,但并不添加view,返回的是xml渲染出的view。
分析具体案例
根据前面的参数情况,我们再来分析案例,案例1
LinearLayout layout = (LinearLayout)findViewById(R.id.container); View view = View.inflate(this, R.layout.layout_menu_item, null);//返回的view是xml对应的view layout.addView(view);
这对应第一种参数情况,这样layoutparamete是没有的,包括layout_width和layout_height
案例2
LinearLayout layout = (LinearLayout)findViewById(R.id.container); View view = View.inflate(this, R.layout.layout_menu_item, layout);这个对应低2种参数情况,返回的view是layout,而不是xml对应的view
案例3
LinearLayout layout = (LinearLayout)findViewById(R.id.container); View v1 = LayoutInflater.from(this).inflate(R.layout.layout_menu_item, null); layout.addView(v1, 200, 200);这个对应第一种参数情况,宽高为200,200
案例4
LinearLayout layout = (LinearLayout)findViewById(R.id.container); View v1 = LayoutInflater.from(this).inflate(R.layout.layout_menu_item, layout, false); layout.addView(v1);对应第三种参数情况,返回的v1是渲染好的xml对应的view而不是root
案例5
LinearLayout layout = (LinearLayout)findViewById(R.id.container); View v1 = LayoutInflater.from(this).inflate(R.layout.layout_menu_item, layout, true);对应第二种情况返回root
案例6
BaseAdapter中往往有这样的代码public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.listview_demo3_item, null); holder.img = (ImageView) convertView.findViewById(R.id.img); holder.title = (TextView) convertView.findViewById(R.id.title); 。。。。
我们会发现layout_menu_item的跟布局的宽高是无效的,那如果我想要跟布局的宽高有效,该怎么办呢?看看inflate那行代码。
用convertView = mInflater.inflate(R.layout.listview_demo3_item,parent,false);
这样就可以了。
总结
1.需要把view按照宽高信息(本质是布局信息)添加到view,得用LinearLayout layout = (LinearLayout)findViewById(R.id.container); View root = View.inflate(this, R.layout.layout_menu_item, layout);这时候返回的是root。
2.需要把view按照宽高信息(本质是布局信息)添加到view,并且想要返回view而不是root,得用
LinearLayout layout = (LinearLayout)findViewById(R.id.container); View v1 = LayoutInflater.from(this).inflate(R.layout.layout_menu_item, layout, false); layout.addView(v1);
3.setContentView的另一种写法,为了得到content这个viewGroup
rootView = (FrameLayout) LayoutInflater.from(this).inflate(getResId(), null); setContentView(rootView);
相关文章推荐
- mysqldump执行时Got error: 1045: Access denied for user 'root'@'localhost' (using p
- 写在开始,于无助的研一
- Struts2 中 OGNL各作用域对象怎么取
- class.getResource.getPath()中文空格转义问题
- NAT穿透相关知识
- MMDrawerController使不需要的页面不滑动
- UML类图几种关系的总结
- springmvc附件上传核心代码
- LoadRunner——loadrunner 运行场景-运行时设置
- 页面通过key获得后台传的Map
- Android应用架构
- 修改tomcat默认的编码方式
- 网站架构
- Linux基本的vi命令
- 基于注解的Spring AOP的配置和使用
- Java解析HTML之HTMLParser使用与详解
- netmap分析(3)-原理分析之数据结构关系
- ios如何禁用旋转使用 MMDrawerConroller 是一些 ViewControllers 呢?
- windows7 64位安装mysql 5.7.11 zip压缩版
- java servlet的工作原理