android:layout_weight属性的使用方法总结

 原创文章,转载请注明出处http://www.cnblogs.com/baipengzhan/p/6282826.html                      

android:layout_weight属性可以和其他属性配合使用,产生多种效果,但如果我们不清楚各种配合的使用,也容易产生一些

意想不到的结果,今天我们就认真的总结一下android:layout_weight属性的各种用法和产生的效果,方便今后直接拿来使用。

 

首先声明一句,我们一般只在LinearLayout中使用该属性,以下各种情况都是在LinearLayout中产生的效果,这点请注意。

我们不能孤立的谈论android:layout_weight属性产生的效果,需要结合其他属性、对象中的内容等等情况。

 

我先说一下本文得出的结论,若您只对结论感兴趣读完结论即可。结论之后是用几个简单例子做的说明,若您有兴趣可以继续阅读。 

 

结论:

 

结合以以下个简单例子的分析,我们来总结一下获得的经验:

 

注意,这里我们是以水平方向为例的,竖直方向的道理相同,适当变通即可。

 

①当android:layout_width属性值为0dp时,无论子控件的内容有多少,子控件占用空间的比例严格正比于android:layout_weight属性值;

 

②当android:layout_width属性值为wrap_content时,子控件占用空间的比例和子控件中的内容多少有关,和内容多少成正比例关系, 

所有设置android:layout_weight属性的控件填满父控件,若所有子控件都没设置该属性,或该属性值为0,则所有子控件的长度只是自己

包裹内容的长度,父控件不一定会填满;

 

③当android:layout_width属性值为match_content时,子控件占用空间的大小和内容多少无关,具体值按照以下公式计算: 

子控件占用空间大小 = android:layout_width属性值 + 剩余空间 * android:layout_weight所占比例 

公式解释: 

android:layout_width属性值:一般我们设置三种,第一种为固定值,比如10dp。第二种为wrap_content,包裹内容,子控件决定该值大小。第三种为match_parent,父控件决定该值大小。 

                                          在本情况下,这个属性值都是match_parent。 

剩余空间:就是子控件所在父控件的空间减去三个子控件android:layout_width之和,剩余空间的大小。在本情况下,父控件就是LinearLayout,它的宽度减去三个TextView宽度之和,也就是 

父控件宽度 - (父控件宽度 + 父控件宽度 + 父控件宽度) = -2 * 父控件宽度。 

android:layout_weight所占比例:某个控件占所有控件的android:layout_weight比例,在本情况下,第一个控件的比例为1/(1 + 2 + 2)。 

 

④父控件中使用android:weightSum属性,相当于为所有子控件指定了所有android:layout_weight之和,

当子控件的android:layout_width属性为match_parent时,会对子控件占用空间的大小产生影响,对

其它情况无影响。子控件的具体值可以参考情况八的计算公式,只是公式中子控件的android:layout_weight

所占比例,由某一子控件占所有子控件weight值之和的比例,变成了某一子控件占android:weightSum值的比例。

 

 以下是具体示例分析,对应于上边的结论,请结合您的具体情况选择阅读。

 

下面我们使用几个简单的例子来说明

 

我们在一个横向的LinearLayout中布置三个TextView,通过改变android:layout_width属性值、android:layout_weight

属性值以及TextView中文字的内容来观察效果和总结android:layout_weight的使用方法。当然啦,垂向的情况只是将

android:layout_height属性和android:layout_weight属性值以及TextView中文字的内容配合使用,请各位小伙伴继续探索,

本文就不列出垂向的情况了。 

 

用途:

①若您想使所有子控件占用空间相等,可以参考情况一,二,五,七设置;

②若您想使所有子控件严格按照设置的weight值占用空间,可以参考情况三;

③若您想使所有子控件填满父控件,但每个子控件随其中内容的多少而改变占用的空间,可以参考情况六;

④若您想使一部分子控件按照自己包裹内容的大小决定占用空间,剩余空间由其他子控件填满,可以参考情况四;

⑤若您想使每个子控件的weight值设置的越大,子控件占用的空间反而越小,可以参考情况八;

⑥若您想在父控件中指定weight值的总和,从而决定子控件占用空间的大小,可以参考情况九;

 

我们总结了以下几种情况:

 

情况一:三个TextView的android:layout_width属性值为0dp,三个TextView内容相同,三个TextView的android:layout_weight

属性值相同

出现的效果为:三者所占用的空间相同,即三者平分水平方向的空间。

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    >

    <TextView android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#f00"
        android:layout_weight="1"
        android:text="1" />

    <TextView android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#0f0"
        android:layout_weight="1"
        android:text="2" />

    <TextView android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#00f"
        android:layout_weight="1"
        android:text="3" />

</LinearLayout>

 

 

分析:这种情况在我们实际使用中用的最多,结合以上参数的设置,我们比较容易理解。

 

情况二:三个TextView的android:layout_width属性值为0dp,三个TextView内容长短不同,三个TextView的android:layout_weight

属性值相同。

出现的效果为:三者所占用的空间相同,即三者平分水平方向的空间。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    >

    <TextView android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#f00"
        android:layout_weight="1"
        android:text="111111111111111111" />

    <TextView android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#0f0"
        android:layout_weight="1"
        android:text="2" />

    <TextView android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#00f"
        android:layout_weight="1"
        android:text="3" />

</LinearLayout>

  

分析:这种情况和第一种情况相比,改变了第一个TextView中的内容长度,从最终的结果来看,我们可以得出结论:

当三个TextView的android:layout_width属性值为0dp,三个TextViewandroid:layout_weight属性值相同时,

无论其中的内容长度,三者在水平方向占用的空间都相同。

 

情况三:三个TextView的android:layout_width属性值为0dp,三个TextView内容长短不同,三个TextView的android:layout_weight

属性值不同。

出现的效果为:三者所占用的空间大小与android:layout_weight属性值大小成正比例。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    >

    <TextView android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#f00"
        android:layout_weight="1"
        android:text="111111111111111111" />

    <TextView android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#0f0"
        android:layout_weight="2"
        android:text="2" />

    <TextView android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#00f"
        android:layout_weight="3"
        android:text="3" />

</LinearLayout>

  

 分析:三个TextView设置的android:layout_weight属性值分别为1,2,3,三者在水平方向占用的

空间大小也按此比例。

 

情况四:两个TextView的android:layout_width属性值为0dp,一个TextView的android:layout_width属性值为wrap_content,

三个TextView内容长短相同,前两个TextView的android:layout_weight属性值相同,第三个TextView的android:layout_weight

属性不设置,或者设置为0。

出现的效果为:第三个TextView占用的空间大小为其中内容的大小,前两个TextView将剩余的空间平分。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    >

    <TextView android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#f00"
        android:layout_weight="1"
        android:text="1" />

    <TextView android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#0f0"
        android:layout_weight="1"
        android:text="2" />

    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#00f"
        android:layout_weight="0"
        android:text="3" />

</LinearLayout>

  

分析:第三个TextView不设置android:layout_weight属性值或者属性值设置为0时,该属性不起作用,控件水平

占用控件为包裹内容,这时,整个水平方向会剩下一部分空间,这个空间由前两个TextView占满,这两个空间的大小

会按照它们设置的比例决定。

 

情况五:三个TextView的android:layout_width属性值为android:wrap_content,三个TextView内容相同,三个TextView的android:layout_weight

属性值相同。

出现的效果为:三者所占用的空间相同,即三者平分水平方向的空间。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    >

    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#f00"
        android:layout_weight="1"
        android:text="1" />

    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#0f0"
        android:layout_weight="1"
        android:text="2" />

    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#00f"
        android:layout_weight="1"
        android:text="3" />

</LinearLayout>

  

分析:这种情况比较简单,出现占用的比例相同的结果,但是和android:layout_width属性为0dp情况有些不同,

当其中的文字长度不同时,会按照文字长度而变化,请看下一种情况。

 

情况六:三个TextView的android:layout_width属性值为android:wrap_content,三个TextView内容不同,三个TextView的android:layout_weight

属性值相同。

出现的效果为:三者所占用的空间随着其中包裹内容的长度而变化。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    >

    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#f00"
        android:layout_weight="1"
        android:text="11111111" />

    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#0f0"
        android:layout_weight="1"
        android:text="22222" />

    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#00f"
        android:layout_weight="1"
        android:text="3" />

</LinearLayout>

  

分析:可见当TextView的android:layout_width属性值为android:wrap_content时,android:layout_weight属性不起作用。

 

当android:layout_width属性设置为match_parent时,会出现一些不同的变化,请看下面的情况。

情况七:三个TextView的android:layout_width属性值为android:match_parent,三个TextView内容不同,三个TextView的android:layout_weight

属性值相同。

出现的效果为:三者所占用的空间相同。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    >

    <TextView android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#f00"
        android:layout_weight="1"
        android:text="11111111" />

    <TextView android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#0f0"
        android:layout_weight="1"
        android:text="22222" />

    <TextView android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#00f"
        android:layout_weight="1"
        android:text="3" />

</LinearLayout>

 

分析:可以明显看到这种情况和第六种情况不同,占用空间不随内容长短而变化。

那当android:layout_weight属性值不同时,会出现什么结果呢?出现的结果与前几种情况非常不同,请看下面的情况。

情况八:三个TextView的android:layout_width属性值为android:match_parent,三个TextView内容相同,三个TextView的android:layout_weight

属性值不同。

出现的效果为:三者所占用的空间不同,但不是按照android:layout_weight属性值的正比例。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    >

    <TextView android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#f00"
        android:layout_weight="1"
        android:text="1" />

    <TextView android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#0f0"
        android:layout_weight="2"
        android:text="2" />

    <TextView android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="26sp"
        android:background="#00f"
        android:layout_weight="2"
        android:text="3" />

</LinearLayout>

  

 分析:第一个android:layout_weight属性值设置得比后两个TextView小,但是占用空间大,这个在直觉上感觉比较奇怪,

其占用空间的具体大小数值为以下分析过程:

 子控件占用空间大小 = android:layout_width属性值 + 剩余空间 * android:layout_weight所占比例

公式解释:

android:layout_width属性值:一般我们设置三种,第一种为固定值,比如10dp。第二种为wrap_content,包裹内容,子控件决定该值大小。第三种为match_parent,父控件决定该值大小。

                                          在本情况下,这个属性值都是match_parent。

剩余空间:就是子控件所在父控件的空间减去三个子控件android:layout_width之和,剩余空间的大小。在本情况下,父控件就是LinearLayout,它的宽度减去三个TextView宽度之和,也就是

父控件宽度 - (父控件宽度 + 父控件宽度 + 父控件宽度) = -2 * 父控件宽度。

android:layout_weight所占比例:某个控件占所有控件的android:layout_weight比例,在本情况下,第一个控件的比例为1/(1 + 2 + 2)。

 

那让我们具体计算一下本情况下三个控件的宽度:

第一个TextView宽度 = 父控件宽度 + (-2 * 父控件宽度) * (1/(1 + 2 + 2)) = 3/5父控件宽度。

第二个TextView宽度 = 父控件宽度 + (-2 * 父控件宽度) * (2/(1 + 2 + 2)) = 1/5父控件宽度。

第三个TextView宽度 = 父控件宽度 + (-2 * 父控件宽度) * (2/(1 + 2 + 2)) = 1/5父控件宽度。

 

这样的计算结果就可以解释本情况图形的结果了。

 

情况九:关于父控件中使用android:weightSum属性的情况。

父控件中使用android:weightSum属性,相当于为所有子控件指定了所有android:layout_weight之和,

当子控件的android:layout_width属性为match_parent时,会对子控件占用空间的大小产生影响,对

其它情况无影响。子控件的具体值可以参考情况八的计算公式,只是公式中子控件的android:layout_weight

所占比例,由某一子控件占所有子控件weight值之和的比例,变成了某一子控件占android:weightSum值

的比例。以情况八为例:子控件的android:layout_weight值所占比例由:

TextView1的android:lalyout_weight / (TextView1的android:lalyout_weight + TextView2的android:lalyout_weight + TextView3的android:lalyout_weight)

变成了:

TextView1的android:lalyout_weight / (android:layout_weight)。

 

此外,我们还要明白一些注意事项:

①按照以上公式计算出负值的控件不会显示在界面上,但显示出的控件宽度还受未出现控件属性值的影响,也遵守上述公式;

②父控件最左边肯定对应着某一个子控件的最左边,不能有子控件的一部分出现在父控件最左侧之外;

③父控件最右边不会限制子控件的最右边,子控件的右侧边可以出现在父控件右侧边之外,只是伸出去的部分不显示;

 

结合以上计算公式和列出的注意情况,可以解决和解释更多由本情况延伸出的情况,请各位小伙伴再深入研究,本文就不赘述了。 

 

总结:

结合以上几个简单例子的分析,我们来总结一下获得的经验:

注意,这里我们是以水平方向为例的,竖直方向的道理相同,适当变通即可。

①当android:layout_width属性值为0dp时,无论子控件的内容有多少,子控件占用空间的比例严格正比于android:layout_weight属性值;

②当android:layout_width属性值为wrap_content时,子控件占用空间的比例和子控件中的内容多少有关,和内容多少成正比例关系,

所有设置android:layout_weight属性的控件填满父控件,若所有子控件都没设置该属性,或该属性值为0,则所有子控件的长度只是自己

包裹内容的长度,父控件不一定会填满;

③当android:layout_width属性值为match_content时,子控件占用空间的大小和内容多少无关,具体值按照以下公式计算:

子控件占用空间大小 = android:layout_width属性值 + 剩余空间 * android:layout_weight所占比例

公式解释:

android:layout_width属性值:一般我们设置三种,第一种为固定值,比如10dp。第二种为wrap_content,包裹内容,子控件决定该值大小。第三种为match_parent,父控件决定该值大小。

                                          在本情况下,这个属性值都是match_parent。

剩余空间:就是子控件所在父控件的空间减去三个子控件android:layout_width之和,剩余空间的大小。在本情况下,父控件就是LinearLayout,它的宽度减去三个TextView宽度之和,也就是

父控件宽度 - (父控件宽度 + 父控件宽度 + 父控件宽度) = -2 * 父控件宽度。

android:layout_weight所占比例:某个控件占所有控件的android:layout_weight比例,在本情况下,第一个控件的比例为1/(1 + 2 + 2);

④父控件中使用android:weightSum属性,相当于为所有子控件指定了所有android:layout_weight之和,

当子控件的android:layout_width属性为match_parent时,会对子控件占用空间的大小产生影响,对

其它情况无影响。子控件的具体值可以参考情况八的计算公式,只是公式中子控件的android:layout_weight

所占比例,由某一子控件占所有子控件weight值之和的比例,变成了某一子控件占android:weightSum值

的比例。

 

说明:本文并没有完全说明android:layout_weight的所有用法。

希望对您有所帮助!

posted @ 2017-01-13 20:27  chironmy  阅读(4375)  评论(0编辑  收藏  举报