剖析Android 线性布局中的权重(layout_weight)(解答疑惑)
首先看一下奇怪的的现象:
线性布局的情况下,有个非常奇怪的属性——android:layout_weight,该属性大部分视图控件中都有,它表示视图的重要度或者权重,看看以下两种情况下该属性的使用:
(1)水平布局的情况下:(android:orientation="horizontal")
第一种情况:设置 android: layout_width="fill_parent" 。
这个时候设置第一个TextView和第二个TextView的layout_weight的值分别为1和2,那么在水平方向上第一个TextView占据了三分之二的宽度,而第二个占据了三分之一的宽度。 也就是在这种情况下,layout_weight的值越大,重要度越低,也就是说占据的宽度越短(不太明白为什么叫重要度,而且这样描述也不太合理,姑且叫他重要度吧)。
第二种情况:设置android: layout_width="wrap_content"。
两个TextView的layout_weight同样是1和2,此时第一个TextView占了三分之一的宽度,而第二个TextView却占用了三分之二,跟上面的情况刚好相反。
(2)垂直布局的情况下:(android:orientation="vertical")
第一种情况:设置android:layout_height="fill_parent"。
设置android:layout_height="fill_parent",两个TextView的设置如下图所示,第一个TextView的高度占了三分之二,而第二个TextView只占了三分一。
第二种情况:设置android:layout_height="wrap_content"。
两个TextView的android:layout_height设置均为wrap_content,第一个TextView的高度占了三分之一,而第二个TextView占了三分之二。(图片就不贴了)
总结
根据上面的四个不同场景,可以知道官方说:“layout_weight数值越小,其重要度越高,即占的宽度或者高度份额越大”,可见它是已fill_parent为基准的。
我们看到上面现象一定会有疑问,为什么会出现相反的情况呢!这个使用layout_weight常会遇到的问题。
下面我们看一下“专家”是怎么分析其原理的:
当前布局效果如图1-1所示。 从图1-1可以看出,黑色部分的宽度是240像素,绿色部分的宽度是80像素,这两部分所占区域宽度的计算方式如下所示: 当前屏幕横屏宽度:320dp 第一个子控件未分配权重前所占宽度:0dp 第二个子控件未分配权重前所占宽度:0dp 当前屏幕剩余空间总数:320dp-0dp-0dp = 320dp,将当前320dp按权重分配给两个子控件,子控件一分配到四分之三,子控件二分配到四分之一 第一个子控件分配权重后宽度:0dp+((320dp-0dp-0dp)*3)/4 = 240dp 第二个子控件分配权重后宽度:0dp+(320dp-0dp-0dp)/4 = 80dp
案例二
图1-2布局效果 从图1-2可以看出,黑色部分的宽度是210像素,绿色部分的宽度是110像素,这两部分所占区域宽度的计算方式如下所示: 当前屏幕横屏宽度:320dp 第一个子控件未分配权重前所占宽度:60dp 第二个子控件未分配权重前所占宽度:60dp 当前屏幕剩余空间总数:320dp-60dp-60dp = 200dp,将当前200dp按权重分配给两个子控件,子控件一分配到四分之三,子控件二分配到四分之一 第一个子控件分配权重后宽度:60dp+((320dp-60dp-60dp)*3)/4 = 210dp 第二个子控件分配权重后宽度:60dp+(320dp-60dp-60dp)/4 = 110dp 案例三
当前布局效果如图1-3所示。 从图1-3可以看出,黑色部分的宽度是110像素,绿色部分的宽度是210像素,这两部分所占区域宽度的计算方式如下所示: 当前屏幕横屏宽度:320dp 第一个子控件未分配权重前所占宽度:260dp 第二个子控件未分配权重前所占宽度:260dp 当前屏幕剩余空间总数:320dp-260dp-260dp = -200dp,将当前-200dp按权重分配给两个子控件,子控件一分配到四分之三,子控件二分配到四分之一 第一个子控件分配权重后宽度:260dp+((320dp-260dp-260dp)*3)/4 = 110dp 第二个子控件分配权重后宽度:260dp+(320dp-260dp-260dp)/4 = 210dp 案例四
从图1-4可以看出,黑色部分的宽度是80像素,绿色部分的宽度是240像素,这两部分所占区域宽度的计算方式如下所示: 当前屏幕横屏宽度:320dp 第一个子控件未分配权重前所占宽度:fill_parent 即为充满横屏 第二个子控件未分配权重前所占宽度:fill_parent 即为充满横屏 当前屏幕剩余空间总数:320dp-320dp-320dp = -320dp,将当前-320dp按权重分配给两个子控件,子控件一分配到四分之三,子控件二分配到四分之一 第一个子控件分配权重后宽度:320dp+((320dp-320dp-320dp)*3)/4 = 80dp 第二个子控件分配权重后宽度:320dp+(320dp-320dp-320dp)/4 = 240dp 案例总结 从上述案例可以看出,如果对线性布局中的控件设置了权重(layout_weight),那么控件占用的空间大小是可以计算出来的,计算公式如下: 线性布局中子控件最终占用宽度 = 原有宽度+剩余空间分配量 例如,在水平方向上的线性布局LinearLayout控件L中,包含两个水平占用空间的控件A、B,其中: L控件:L控件宽度layout_width = width_l A控件:A控件宽度layout_width = width_a A控件权重layout_weight = weight_a B控件:B控件宽度layout_width = width_b B控件权重layout_weight = weight_b L中子控件最终占用宽度 = 原有宽度(width_a)+剩余空间分配量 A所占宽度 = width_a + (width_l-width_a-width_b)*weight_a/(weight_a+weight_b) B所占宽度 = width_b + (width_l-width_a-width_b)*weight_b/(weight_a+weight_b) 由此可以推断,当使用权重(layout_weight)时,会遇到下列两种情况: 情况1:当L中内部子控件(A,B)的宽度之和大于L的总宽度时,即(width_l-width_a-width_b)<0时,weight_a/(weight_a+weight_b)比例的值越大,当前控件所占空间越小。 情况2:当L中内部子控件(A,B)的宽度之和小于L的总宽度时,即(width_l-width_a-width_b)>0时,weight_a/(weight_a+weight_b)比例的值越大,当前控件所占空间越大。
我们在使用的时候一般情况把要布局的一般吧width或者height设置为0dp
更多相关文章
- 【Android 开发】:UI控件之 ListView 列表控件的使用
- Android 中的时间日期控件
- IKNinePhotoView 是一个开源的 Android 九宫格控件,可以自适应宽
- Android之——自定义复合控件的实现
- Android Chronometer控件开发
- Android 控件一 TextView
- Android 控件二 Button