初始化布局带inflate方法指定父容器的作用

2016-11-16 20:09 阅读 2,746 次 评论 0 条
版权声明:本文著作权归TeachCourse所有,未经许可禁止转载,谢谢支持!
转载请注明出处:http://teachcourse.cn/2094.html

摘要:

ViewGroup是一个特殊的View,它包含着其他的Views,属于布局的基类和Views容器。addView方法往ViewGroup添加子控件,removeView方法移除子控件。初始化布局使用LayoutInflaterinflate方法,有几种方式可以获取LayoutInflater对象,这里不讨论这个,我们来讨论inflate方法之间的区别。

一、inflate方法的区别

inflate(int,ViewGroup,boolean),解析一个xml布局文件,然后将其转换成View对象,int指定布局id,ViewGroup指定当前初始化View的父容器,boolean指定是否依附ViewGroup。inflate的另一个方法是inflate(int,ViewGroup),指定ViewGroup后,默认当前View依附父容器。到底依附父容器和不依附父容器有什么区别呢?指定ViewGroup与设置null又有什么区别?

inflate(int,ViewGroup)方法,初始化一个布局xml资源文件,指定ViewGroup的效果相当于往ViewGroup添加子控件,默认带两个参数的inflate依附于父容器。

查看带两个参数的inflate源码,如下:

  1. /** 
  2.      * Inflate a new view hierarchy from the specified xml resource. Throws 
  3.      * {@link InflateException} if there is an error. 
  4.      *  
  5.      * @param resource ID for an XML layout resource to load (e.g., 
  6.      *        <code>R.layout.main_page</code>) 
  7.      * @param root Optional view to be the parent of the generated hierarchy. 
  8.      * @return The root View of the inflated hierarchy. If root was supplied, 
  9.      *         this is the root View; otherwise it is the root of the inflated 
  10.      *         XML file. 
  11.      */  
  12.     public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {  
  13.         return inflate(resource, root, root != null);  
  14.     }  

内部调用的是带三个参数的inflate方法,如果指定了root,那么root!=null返回true,即childView隶属parentView的一个子控件。

如果将ViewGroup设置为null,初始化布局后,调用ViewGroup的addView,效果等同,代码如下:

  1. View childView=LayoutInflater.from(this).inflate(R.layout.activity_inflate_child,null);  
  2. mParentView.addView(childView);  

效果等同:

  1. LayoutInflater.from(this).inflate(R.layout.activity_inflate_child,mParentView);  

inflate(int,ViewGroup,boolean)方法,多个一个boolean值,为true指定childView隶属parentView的一个子控件,否则ViewGroup仅用于创建正确的LayoutParams子类。查看源码解析,如下:

  1. /** 
  2.      * Inflate a new view hierarchy from the specified xml resource. Throws 
  3.      * {@link InflateException} if there is an error. 
  4.      *  
  5.      * @param resource ID for an XML layout resource to load (e.g., 
  6.      *        <code>R.layout.main_page</code>) 
  7.      * @param root Optional view to be the parent of the generated hierarchy (if 
  8.      *        <em>attachToRoot</em> is true), or else simply an object that 
  9.      *        provides a set of LayoutParams values for root of the returned 
  10.      *        hierarchy (if <em>attachToRoot</em> is false.) 
  11.      * @param attachToRoot Whether the inflated hierarchy should be attached to 
  12.      *        the root parameter? If false, root is only used to create the 
  13.      *        correct subclass of LayoutParams for the root view in the XML. 
  14.      * @return The root View of the inflated hierarchy. If root was supplied and 
  15.      *         attachToRoot is true, this is root; otherwise it is the root of 
  16.      *         the inflated XML file. 
  17.      */  
  18.     public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {  
  19.         final Resources res = getContext().getResources();  
  20.         if (DEBUG) {  
  21.             Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" ("  
  22.                     + Integer.toHexString(resource) + ")");  
  23.         }  
  24.   
  25.         final XmlResourceParser parser = res.getLayout(resource);  
  26.         try {  
  27.             return inflate(parser, root, attachToRoot);  
  28.         } finally {  
  29.             parser.close();  
  30.         }  
  31.     }  

分析源码,发现内部调用了inflate(XmlResourceParser,ViewGroup,boolean)方法,attachToRoot的英文翻译如上文一致,指定被初始化的view是否属于root的元素,如果被设置为false,root仅被用于创建合适的LayoutParams的子类

二、指定ViewGroup的另外一个作用:保证margin、padding属性生效

初始化一个xml布局资源,在初始化的布局root中指定了margin、padding属性,为了保证其生效,Viewgroup不能设置为null。下面具体来看一个例子:初始化多个activity_inflate_child,并添加到activity_inflate中,对比一个指定ViewGroup和没有指定ViewGroup之间的区别

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_marginTop="@dimen/activity_vertical_margin"  
  6.     android:layout_height="match_parent">  
  7.     <TextView  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:layout_gravity="center"  
  11.         android:text="指定子控件的父容器,margin、padding才生效"/>  
  12. </LinearLayout>  

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     android:id="@+id/activity_inflate_ll"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="match_parent"  
  7.     android:orientation="vertical"  
  8.     tools:context="com.sinolvc.zspg.view.inflate.InflateChildActivity">  
  9.   
  10. </LinearLayout>  
  1. /**  
  2.         * 添加第一个子控件,规则:设置ViewGroup  
  3.         */  
  4.        View childView = LayoutInflater.from(this).inflate(R.layout.activity_inflate_child, mParentView_ll, false);  
  5.        mParentView_ll.addView(childView);  
  6.        /**  
  7.         * 添加第二个子控件,规则:不设置ViewGroup  
  8.         */  
  9.        View childView2 = LayoutInflater.from(this).inflate(R.layout.activity_inflate_child, null, false);  
  10.        mParentView_ll.addView(childView2);  
  11.        /**  
  12.         * 添加第三个子控件,规则:设置ViewGroup  
  13.         */  
  14.        View childView3 = LayoutInflater.from(this).inflate(R.layout.activity_inflate_child, mParentView_ll, false);  
  15.        mParentView_ll.addView(childView3);  
  16.        /**  
  17.         * 添加第四个子控件,规则:不设置ViewGroup  
  18.         */  
  19.        View childView4 = LayoutInflater.from(this).inflate(R.layout.activity_inflate_child, null, false);  
  20.        mParentView_ll.addView(childView4);  

最后运行的效果:

001-inflate-layout-view

只有第一个和第三个View的margin、padding值生效,第二个和第四个没有设置ViewGroup,无效。

关注公众号 扫一扫二维码,加我QQ

如果文章对你有帮助,欢迎点击上方按钮关注作者

来源:TeachCourse每周一次,深入学习Android教程,关注(QQ1589359239或公众号TeachCourse)
转载请注明出处:http://teachcourse.cn/2094.html
Conversion to Dalvik format failed Conversion to Dalvik format
LayoutParams通知父容器childView被放置在哪里 LayoutParams通知父容器childV
对象系列化两种方法Serializable和Parcelable 对象系列化两种方法Serializabl
关于Bitmap位图压缩图片的三种方式 关于Bitmap位图压缩图片的三种方

发表评论

呲牙 憨笑 坏笑 偷笑 色 微笑 抓狂 睡觉 酷 流汗 鼓掌 大哭 可怜 疑问 晕 惊讶 得意 尴尬 发怒 奋斗 衰 骷髅 啤酒 吃饭 礼物 强 弱 握手 OK NO 勾引 拳头 差劲 爱你

表情