Android-LinearLayout中的layout_weight属性
前言
layout_weight 看起来像“让控件自动按比例变宽/变窄”,但真正理解它需要搞清楚:权重只是在“剩余空间”怎么分配上起作用。
下面用一个简化模型,把计算过程拆开讲清楚。
本文只讨论水平方向(横向)。
简化公式
1 | 实际宽度 = 基础宽度 + 剩余宽度 * (weight / weight总和) |
说明(简化模型):
- 基础宽度:参与测量时先确定出来的那部分宽度(例如固定值,或
wrap_content测得的内容宽度;在一些场景下layout_width="0dp"时基础宽度为 0)。 - 剩余宽度:容器最终可用宽度减去所有基础宽度之和。
- weight总和:参与权重分配的子 View 的
layout_weight之和。
示例 1:剩余空间为负(权重越大反而宽度越小)
设 LinearLayout 宽度为 400,内部有两个 TextView:textView1、textView2。
textView1 的宽度是 match_parent,layout_weight 是 2textView2 的宽度是 match_parent,layout_weight 是 3
为了说明机制,这里把基础宽度视为先测出的宽度:
- 基础宽度:
textView1 = 400,textView2 = 400 - 剩余宽度:
400 - 400 - 400 = -400 - 权重比:
2/5、3/5
按公式计算:
textView1实际宽度:400 + (-400) * (2/5) = 240textView2实际宽度:400 + (-400) * (3/5) = 160
小结:当剩余宽度为负时,表示基础宽度之和已经“超出了”容器宽度。此时 weight 也会把负剩余按比例分摊,所以 weight 越大,最终宽度反而越小。(真实项目不建议把 match_parent 和 layout_weight 混用,这里仅用于说明计算过程。)
示例 2:剩余空间为正(按比例分配)
设 LinearLayout 宽度为 400,两个 TextView 都是 wrap_content,并且测得内容宽度如下:
textView1 的内容宽度为 100,layout_weight 为 1textView2 的内容宽度为 150,layout_weight 为 4
基础宽度之和:100 + 150 = 250
剩余宽度:400 - 250 = 150
权重比:1/5、4/5
按公式计算:
textView1实际宽度:100 + 150 * (1/5) = 130textView2实际宽度:150 + 150 * (4/5) = 270
写出 2:3 的比例(最推荐)
如果你希望 textView1:textView2 = 2:3(即权重比为 2/5 和 3/5),最常用也最稳的写法是:让它们由 weight 决定分配空间,也就是把宽度设为 0dp。
1 | <TextView |
此时容器宽度由父布局确定,剩余空间就会按 2:3 分配。
常见误区
- 如果某些子 View 不是
0dp(固定宽度或wrap_content),weight 只负责“剩余空间”的分配,最终比例不一定严格等于 weight 的比例。 - 想要“纯按比例分配”,优先使用
0dp + layout_weight(或竖向对应的0dp + layout_height)。