原创文章,转载请注明出处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的所有用法。
希望对您有所帮助!