Android见习收获:UI细节bug引发的layout_weight深入理解

Android实习收获:UI细节bug引发的layout_weight深入理解

今天在修改一个布局问题时候,发现自己对权重的理解还不够。

首先问题如图:

Android见习收获:UI细节bug引发的layout_weight深入理解

一个TextView没有按要求显示完整,显示成了2行。

怎么办呢?

  1. 方法1:是把它左面的字体放小。
    结果师兄说不可以随意修改布局的尺寸,否则测试还会提bug。

  2. 方法2:不让改字体,那就修改边距,图片的margin,textView的magin,统统改了遍。
    结果可想而知,这么大的变动更不可以。

  3. 师兄看我这么愚钝,指点了一下:不修改布局,怎样能让时间不论在什么情况下都显示呢?

    • 我的做法:
            <TextView
                android:id="@+id/teacher_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="张文欣老师回答了您的问题"
                android:textColor="@color/color_blackest_text"
                android:textSize="@dimen/text_size_mediumer" />

            <TextView
                android:id="@+id/notice_time"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:singleLine="true"
                android:layout_marginLeft="3dp"
                android:text="5-16 4:04"
                android:textSize="@dimen/text_size_smaller" />
  • 显示布局:

Android见习收获:UI细节bug引发的layout_weight深入理解

  • 还是那样。
  • 为什么呢? 设置layout_weight = “1”不就是为了保证它在什么情况下都显示吗?怎么回事。

4。师兄看不下去了,亲自示范给我,代码如下:

 <TextView
                android:id="@+id/teacher_name"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:singleLine="true"
                android:text="张文欣老师回答了您的问题"
                android:textColor="@color/color_blackest_text"
                android:textSize="@dimen/text_size_mediumer" />

            <TextView
                android:id="@+id/notice_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="3dp"
                android:text="5-16 4:04"
                android:textSize="@dimen/text_size_smaller" />
  • 哇塞,这次ok了:
    Android见习收获:UI细节bug引发的layout_weight深入理解

虽然一样都是设置layout_weight,但是设置在什么位置就显示出了对它的理解。

我之前的理解一直都是把某个组件的宽或者高设置为0,然后再设置个权重为1,它就会填充所有剩下的空间。事实上很多时候也奏效了。

今天这次让我仔细看了之前的一篇文章【Android入门的常见问题Part1】android:layout_weight的理解,结合这次的问题,好好思考了一下layout_weight的用法。

用法总结:

  1. 最常见的使用权重都是设置宽或者高为0dp,然后设置权重为1.而且整个布局中只有这一个权重。

    • 比如说在一个listView下有个button,listView高度不确定,想让button始终显示,就给listView设置个权重。
    • 为什么这么用会有这样的效果呢?
    • 首先要明白,layout_weight表示的是对剩余空间的占有比例,我再强调一下,是剩余!
    • 既然是挑剩下的,那自然应该先让除他以外的其他组件显示。
    • 就比如说开篇的那个问题,想让显示时间的TextView不论何时都显示,就给其他的某个不太重要的组件设置权重,让那个不重要的自己根据剩余空间显示大小。
  2. 还有的时候我们布局中不仅一个权重,比如说为了屏幕适配,给布局中的所有子组件都设置权重,那么子组件就会占据权重响应的比例。

    • 比如说:
<LinearLayout  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content"  
            android:orientation="vertical" >  

            <Button  
                android:id="@+id/button1"  
                android:layout_width="0dp"  
                android:layout_height="wrap_content"  
                android:layout_weight="2"  
                android:text="1"  
                android:textSize="20sp" />  
            <Button  
                android:id="@+id/button2"  
                android:layout_width="0dp"  
                android:layout_height="wrap_content"  
                android:layout_weight="1"  
                android:text="2"  
                android:textSize="20sp" />  
</LinearLayout>

Android见习收获:UI细节bug引发的layout_weight深入理解
- button1会占据2/3的位置,button2会占据1/3.
- 注意,两个Button的宽度都是0dp

3.在2的情况下,我们设置Button的宽度为wrap_content:

<LinearLayout  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content"  
            android:orientation="horizontal" >  

            <Button  
                android:id="@+id/button1"  
                android:layout_width="wrap_content"  
                android:layout_height="wrap_content"  
                android:layout_weight="2"  
                android:text="1"  
                android:textSize="20sp" />  
            <Button  
                android:id="@+id/button2"  
                android:layout_width="wrap_content"  
                android:layout_height="wrap_content"  
                android:layout_weight="1"  
                android:text="2"  
                android:textSize="20sp" />  
</LinearLayout>

Android见习收获:UI细节bug引发的layout_weight深入理解

  • 还是之前强调的,layout_weight分配的是剩余的空间
  • 上述代码中我们将2个按钮的宽度都设为wrap_content,假设他俩宽度都是2,整个布局宽度为10.
  • 那么button1实际得到的宽度是:2 + (10 -2 -2)*(2/3) = 6
  • button2实际得到的宽度是: 2 + (10 -2 -2)*(1/3) = 4

4.在3的情况下,我们设置Button的宽度为match_parent:

<LinearLayout  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content"  
            android:orientation="horizontal" >  

            <Button  
                android:id="@+id/button1"  
                android:layout_width="match_parent"  
                android:layout_height="wrap_content"  
                android:layout_weight="2"  
                android:text="1"  
                android:textSize="20sp" />  
            <Button  
                android:id="@+id/button2"  
                android:layout_width="match_parent"  
                android:layout_height="wrap_content"  
                android:layout_weight="1"  
                android:text="2"  
                android:textSize="20sp" />  
</LinearLayout>

Android见习收获:UI细节bug引发的layout_weight深入理解

  • 我们看到1和2的比例相反了,为什么呢?
  • 上述代码中我们将第一个按钮就设置为match_parent,即填充整个布局。第二个也设置为match_parent,如果没有权重,第二个是不会显示的。
  • 如果两个组件所占的空间之和超过了整个空间的大小,假设整个布局的宽度为10,2个按钮由于设置match_parent理论上的宽度也分别为10,这样2个组件超过了空间,该怎么分配呢?
  • 超出的部分也按照权重来分,不过是在组件原来占有空间的基础上来减去这个值
  • 所以2个按钮实际得到的大小为:
  • button1实际得到的宽度是:10-(10+10-10)*2/3=1/3个空间大小
  • button2实际得到的宽度是: 10-(10+10-10)*1/3=2/3个空间大小。

这就解释了为什么有时候weight值大,占有的权重反而小。

权重所占的比例与对应的宽度、高度有关,视情况而定,不可死记硬背。

不过要理解的就是分配的是剩下的空间,优先级最低。

1楼u011240877昨天 14:00
其实也可以简单的记为:当组件大小没超过父布局时,与权重成正比;超过父布局时,与权重成反比
Re: u011240877昨天 14:05
回复u011240877n刚才测试了下,发现这个规律不对,还是和尺寸有关,当尺寸为0时、或者为match_parent才与权重有正、反比关系