android:layout_weight的真实含义

     首先声明只有在Linearlayout中,该属性才有效。之所以android:layout_weight会引起争议,是因为在设置该属性的同时,设置android:layout_width为wrap_content和match_parent会造成两种截然相反的效果。如下所示:

<LinearLayout  
       android:layout_width="match_parent"  
       android:layout_height="wrap_content"  
       android:orientation="horizontal" >  
  
       <TextView  
           android:layout_width="match_parent"  
           android:layout_height="wrap_content"  
           android:layout_weight="1"  
           android:background="@android:color/black"  
           android:text="111"  
           android:textSize="20sp" />  
  
       <TextView  
           android:layout_width="match_parent"  
           android:layout_height="wrap_content"  
           android:layout_weight="2"  
           android:background="@android:color/holo_green_light"  
           android:text="222"  
           android:textSize="20sp" /> 
</LinearLayout>

 



上面的布局将两个TextView的宽度均设为match_parent,一个权重为1,一个权重为2.得到效果如下:


李胜松博客

可以看到权重为1的反而占了三分之二!

再看如下布局:

<LinearLayout  
    android:layout_width="match_parent"  
    android:layout_height="wrap_content"  
    android:orientation="horizontal" >  
  
    <TextView  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_weight="1"  
        android:background="@android:color/black"  
        android:text="111"  
        android:textSize="20sp" />  
  
    <TextView  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_weight="2"  
        android:background="@android:color/holo_green_light"  
        android:text="222"  
        android:textSize="20sp" />  
</LinearLayout>

 即宽度为wrap_content,得到视图如下:


李胜松博客

左边 TextView占比三分之一,又正常了。

android:layout_weight的真实含义是:一旦View设置了该属性(假设有效的情况下),那么该 View的宽度等于原有宽度(android:layout_width)加上剩余空间的占比!

设屏幕宽度为L,在两个view的宽度都为match_parent的情况下,原有宽度为L,两个的View的宽度都为L,那么剩余宽度为L-(L+L) = -L, 左边的View占比三分之一,所以总宽度是L+(-L)*1/3 = (2/3)L.事实上默认的View的weight这个值为0,一旦设置了这个值,那么所在view在绘制的时候执行onMeasure两次的原因就在这。

Google官方推荐,当使用weight属性时,将width设为0dip即可,效果跟设成wrap_content是一样的。这样weight就可以理解为占比了!

------------------------------------------------------------------------------------------------------------------------------------------------

扩展:

在Android没有推出android-percent-support-lib之前,甚至在其推出后,一直使用layout_weight实现“百分比”布局。相比于wrap_content和match_parent ,巧妙的使用layout_weight可以很简洁的实现界面按“百分比”布局,当然这其中也有一些奥妙,这里就做一下记录。

首先看一下下面的布局文件

<LinearLayout
       android:layout_width="match_parent"
       android:layout_height="0dp"
       android:layout_weight="1"
       android:orientation="vertical">
       <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:layout_marginTop="20dp"
           android:orientation="horizontal">
           <TextView
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_weight="1"
               android:background="#77bc1f"
               android:text="AAA"
               android:textColor="#fff"
               android:textSize="23sp" />
           <TextView
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_weight="2"
               android:background="#06d992"
               android:text="BBB"
               android:textColor="#fff"
               android:textSize="23sp" />
           <TextView
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_weight="3"
               android:background="#EEA32E"
               android:text="CCC"
               android:textColor="#fff"
               android:textSize="23sp" />
       </LinearLayout>
       <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:layout_marginTop="20dp"
           android:orientation="horizontal">
           <TextView
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:layout_weight="1"
               android:background="#77bc1f"
               android:text="AAA"
               android:textColor="#fff"
               android:textSize="23sp" />
           <TextView
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:layout_weight="2"
               android:background="#06d992"
               android:text="BBB"
               android:textColor="#fff"
               android:textSize="23sp" />
           <TextView
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:layout_weight="3"
               android:background="#EEA32E"
               android:text="CCC"
               android:textColor="#fff"
               android:textSize="23sp" />
       </LinearLayout>
       <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:layout_marginTop="20dp"
           android:orientation="horizontal">
           <TextView
               android:layout_width="0dp"
               android:layout_height="wrap_content"
               android:layout_weight="1"
               android:background="#77bc1f"
               android:text="AAA"
               android:textColor="#fff"
               android:textSize="23sp" />
           <TextView
               android:layout_width="0dp"
               android:layout_height="wrap_content"
               android:layout_weight="2"
               android:background="#06d992"
               android:text="BBB"
               android:textColor="#fff"
               android:textSize="23sp" />
           <TextView
               android:layout_width="0dp"
               android:layout_height="wrap_content"
               android:layout_weight="3"
               android:background="#EEA32E"
               android:text="CCC"
               android:textColor="#fff"
               android:textSize="23sp" />
       </LinearLayout>
   </LinearLayout>

这段代码实现的UI效果如下:


layout_weight

整个布局是个垂直的LinearLayout,里面有三个水平方向的LinearLayout,内部放置了三个TextView,三个TextView高度为wrap_content;其内容和背景色也不同(这里只是为了看起来方便),重点是其宽度:

第一行内三个TextView

layout_width="wrap_content"

第二行内三个TextView

android:layout_width="match_parent"

第三行内三个TextView

android:layout_width="0dp"

而每一个LinearLayout内部三个TextView的layout_weight分别1,2,3。由此,看见由于其wrap_content的不同,使其layout_weight的分配受到了影响。这里就来分析一下,按照之前所说,layout_weight会按屏幕剩余空间,按权重分配空间。

第一种情况(第一个LinearLayout)

系统先给3个TextView分配他们的宽度值wrap_content(宽度足以包含他们的内容1,2,3即可),然后会把剩下来的屏幕空间按照1:2:3的比列分配给3个textview,
上面的UI 比重为 :
61/6 ,62/6,6*3/6  即1:2:3 ,如UI 第一行呈现的那样。

第二种情况(第二个LinearLayout)

系统先给3个textview分配他们所要的宽度match_parent,也就是说每一都是填满他的父控件,这里就是屏幕的宽度
那么这时候的剩余空间=
1个parent_width-3个parent_width=-2个parent_width (parent_width指的是屏幕宽度 )

那么第一个TextView的实际所占宽度应该=match_parent的宽度,
即parent_width + 他所占剩余空间的权重比列1/6 * 剩余空间大小(-2 parent_width)=2/3parent_width

同理第二个TextView的实际所占宽度=parent_width + 2/6*(-2parent_width)=1/3parent_width;

第三个TextView的实际所占宽度=parent_width + 3/6*(-2parent_width)=0parent_width;所以就是2:1:0的比列显示了。

即如UI第二行呈现的那样。

第三种情况

这种情况,其实和第一种是一样的。

看到这里,下次使用layout_weight时,如果放置的控件看不见了,就不会觉得奇怪了。



原文:http://blog.csdn.net/yanzi1225627/article/details/24667299




lss博客
请先登录后发表评论
  • 最新评论
  • 总共0条评论