问题:
我有一个FrameLayout(后面简称frame),我有一个需求,是动态向这个frame中添加一个使用xml定义子view(后面简称xmlview),一般的方法都是使用LayoutInflater动态inflate一个view,然后调用
frame.addViiew,结果发现xmlview的根布局的layout_width 和 layout_height 一直不生效,这特么是什么鬼,不管怎么改都不行,撞鬼了么
原因剖析:
主要原因还是我们对LayoutInflater类中的inflate函数认知不清导致的。
首先,先贴上相关源码:
/** * Inflate a new view hierarchy from the specified xml resource. Throws * {@link InflateException} if there is an error. * * @param resource ID for an XML layout resource to load (e.g.,* <code>R.layout.main_page</code>) * @param root Optional view to be the parent of the generated hierarchy. * @return The root View of the inflated hierarchy. If root was supplied,* this is the root View; otherwise it is the root of the inflated * XML file. */ public View inflate(int resource,ViewGroup root) { return inflate(resource,root,root != null); }
/** * Inflate a new view hierarchy from the specified xml resource. Throws * {@link InflateException} if there is an error. * * @param resource ID for an XML layout resource to load (e.g.,* <code>R.layout.main_page</code>) * @param root Optional view to be the parent of the generated hierarchy (if * <em>attachToRoot</em> is true),or else simply an object that * provides a set of LayoutParams values for root of the returned * hierarchy (if <em>attachToRoot</em> is false.) * @param attachToRoot Whether the inflated hierarchy should be attached to * the root parameter? If false,root is only used to create the * correct subclass of LayoutParams for the root view in the XML. * @return The root View of the inflated hierarchy. If root was supplied and * attachToRoot is true,this is root; otherwise it is the root of * the inflated XML file. */ public View inflate(int resource,ViewGroup root,boolean attachToRoot) { if (DEBUG) System.out.println("INFLATING from resource: " + resource); XmlResourceParser parser = getContext().getResources().getLayout(resource); try { return inflate(parser,attachToRoot); } finally { parser.close(); } }
大家已经注意到了,两个参数的inflate方法其实也是调用三个参数的inflate方法,
inflate(R.layout.demo,frameParent) 则相当于是调用了inflate(R.layout.demo,frameParent,true)
让我们接下来深入infalte具体的执行代码(篇幅问题,只截取了最重要的部分)
相信通过上面的代码大家已经知道为什么xml中根view会丢失width以及heigh属性了吧,原因就是:你在调用inflate函数时候,传了一个null的父布局。
inflate(R.layout.demo,null)
接下来还有一个小点要讲述一下:
inflate(R.layout.demo,null) 返回的view 是 xml本身的根view 丢失了设置的layout_width 以及 layout_height inflate(R.layout.demo,parent)以及 inflate(R.layout.demo,parent,true) 返回的view 是 parent ,而不是xml的根布局</span> inflate(R.layout.demo,false) 返回的view是 xml的根view 但是此时他拥有xml中设置的 layout_width和 layout_height
到这,这个问题已经理清了。