android:layout_weight实例计算详解

在android学习开发中,UI经常要用到LinearLayout,在做一些不同屏幕适配或按比例显示的时候,布局内控件的weight显得非常重要。在学习中发现网上资料五花八门,很容易使人糊涂。
就自己整理网上资料总结下,和大家分享,以期与大家共同学习进步,如有错误请大家批评指正!

下面以控件水平排列说明 ,控件的weight值设置一般分为3种情况:
1、LinearLayout内的控件的layout_width设置为"wrap_content",代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity" >

    <TextView
       android:layout_width="wrap_content"          android:layout_height="fill_parent"
        android:layout_weight="1"
        android:background="#aa0000"
        android:gravity="center"
        android:text="1" />

    <TextView
        android:layout_width="wrap_content"  
        android:layout_height="fill_parent"
        android:layout_weight="2"
        android:background="#00aa00"
        android:gravity="center"
        android:text="2" />

   <TextView
       android:layout_width="wrap_content"  
       android:layout_height="fill_parent"
       android:layout_weight="3"
       android:background="#0000aa"
       android:gravity="center"
       android:text="3" />
 
</LinearLayout

效果图如下:
 


可以看到这三个TextView是按照1:2:3的比例进行显示的,这样看来似乎可以实现按照比例显示了,但是有个问题,如果TextView内的文本长度一同那么较长文本的TextView会宽度会有所增加,
代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity" >

    <TextView
        
android:layout_width="wrap_content"   
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:background="#aa0000"
        android:gravity="center"
        android:text="111111111111111111111111111" />

    <TextView
        android:layout_width="wrap_content"    
        android:layout_height="fill_parent"
        android:layout_weight="2"
        android:background="#00aa00"
        android:gravity="center"
        android:text="2" />

   <TextView
       android:layout_width="wrap_content"  
       android:layout_height="fill_parent"
       android:layout_weight="3"
       android:background="#0000aa"
       android:gravity="center"
       android:text="3" />
  

</LinearLayout



效果图如下:
 



可以看到3个TextView比例并没有按照1:2:3来显示的,似乎达不到所要求的效果了,如何实现效果呢,这就要介绍到第二种layout_width设置为"0dip"了。

2、LinearLayout内的控件的layout_width设置为"0dip",代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity" >

    <TextView
        
android:layout_width="0dip"    
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:background="#aa0000"
        android:gravity="center"
        android:text="1" />

    <TextView
        
android:layout_width="0dip"   
        android:layout_height="fill_parent"
        android:layout_weight="2"
        android:background="#00aa00"
        android:gravity="center"
        android:text="2" />

    <TextView
        
android:layout_width="0dip" 
        android:layout_height="fill_parent"
        android:layout_weight="3"
        android:background="#0000aa"
        android:gravity="center"
        android:text="3" />

</LinearLayout

效果图如下:
 


终于达到了了显示效果了。为什么会是这样,不是说weight值越小,其优先级越高,占用空间越大吗?我们先看看第三种

3、LinearLayout内的控件的layout_width设置为"fill_parent",代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity" >

    <TextView
        
android:layout_width="fill_parent"  
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:background="#aa0000"
        android:gravity="center"
        android:text="1" />

    <TextView
        
android:layout_width="fill_parent"   
        android:layout_height="fill_parent"
        android:layout_weight="2"
        android:background="#00aa00"
        android:gravity="center"
        android:text="2" />

    <TextView
        
android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:layout_weight="3"
        android:background="#0000aa"
        android:gravity="center"
        android:text="3" />

</LinearLayout>

实现效果图如下:
 

什么意思?第三个TextView丢掉了,很是奇怪,让我们再试一个,把weight分别改为2,3,4的看看效果图:
 


可以看到并没有按反比例来显示。

通过以上几种情况来看,似乎让人感到很困惑。好在有大神总结出了一套计算公式,让我豁然开朗,主要如下:
当在linearLayout中包含有weight的child时,linearLayout会measure两次,假设屏幕宽度为X;
1、当所有child的layout_width设置为"fill_parent"时:
控件比例1:2:3
第一次:textview1的measuredWidth为X,textview2为X,textview3也为X (因为用了weight,所以linearLayout每次measure child时不考虑前一个已经占用的大小)
第二次:计算额外的空间a=x-x-x-x=-2x(屏幕宽度-textview1的宽度-textview2的宽度-textview3的宽度)
然后会将
textview1的宽度设为x+a*1/(1+2+3)=2/3x
textview2的宽度为 x+a*2/(1+2+3) =1/3x
textview3的宽度为 x+a*3/(1+2+3) =0x (即第三个textview3不显示)

同理控件比例2:3:4
textview1的宽度设为x+a*2/(2+3+4)=5/9x
textview2的宽度为 x+a*3/(2+3+4) =3/9x
textview3的宽度为 x+a*4/(2+3+4) =1/9x 


2、当所有child的layout_width设置为"0dip"时:
控件比例1:2:3
第一次:textview1的measuredWidth为0,textview2为0,textview3也为0;
第二次:计算额外的空间a=x-0-0-0=x(屏幕宽度-textview1的宽度-textview2的宽度-textview3的宽度)
然后会将
textview1的宽度为0+a*1/(1+2+3)=1/6x
textview2的宽度为 0+a*2/ (1+2+3) =2/6x
textview3的宽度为0+a*3/ (1+2+3) =3/6x 

3个控件就会按照1:2:3的比例来显示。

3、当所有child的layout_width设置为"wrap_content"时:
这种情况,我认为是,如果一个控件在已经大于原有设定的比例时,这个控件将按照自身大小来显示,如没有,则按照原来比列显示。剩下的控件一次类推。




总结:
layout_weight的公式为:

控件的宽度(高度)=控件的width(height)值+(该控件的weight值/所有控件的weight的和)×额外的空间

额外的空间=手机的宽度(高度)-所有控件的宽度(高度)
当了解这个公式后,我们再设计程序时,为了能够自适应屏幕,不想给控件一个指定的宽度和高度,就可以使用这个weight属性来让它按自己比例来划分屏幕高度或者宽度了。


1.png (66.7 KB, 下载次数: 0)

1.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值