- 浏览: 80554 次
- 性别:
- 来自: 北京
文章分类
最新评论
原文地址:http://www.cnblogs.com/angeldevil/archive/2012/04/08/2437747.html
SDK中的解释
Indicates how much of the extra space in the LinearLayout will be allocated to the view associated with these LayoutParams. Specify 0 if the view should not be stretched. Otherwise the extra pixels will be pro-rated among all views whose weight is greater than 0.
重点有两个,一个是layout_weight表示LinearLayout中额外空间的划分(可能扩展应用layout_weight前的大小也可能压缩),另一个是按比例.
以下说的都以 android:orientation="horizontal" 为例
看了一下源码,虽说不太懂,但了解了下大概意思,按照自己的理解总结一下,直接写一下简化的代码吧(下面的代码是LinearLayout源文件中一部分的精简,变量名称含义可能不准确,为叙述方便暂作此解释):
//Either expand children with weight to take up available space or
// shrink them if they extend beyond our current bounds
int delta = widthSize - mTotalLength;
if (delta != 0 && totalWeight > 0.0f) {
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
if (child == null || child.getVisibility() == View.GONE) {
continue;
}
final LinearLayout.LayoutParams lp =
(LinearLayout.LayoutParams) child.getLayoutParams();
float childExtra = lp.weight;
if (childExtra > 0) {
int share = (int) (childExtra * delta / weightSum);
weightSum -= childExtra;
delta -= share;
int childWidth = child.getMeasuredWidth() + share;
if (childWidth < 0) {
childWidth = 0;
}
}
}
}
变量含义
widthSize: LinearLayout的宽度
mTotalLength: 所有子View的宽度的和(还没用考虑layout_weight)
totalWeight: 所有子View的layout_weight的和
mWeihtSUm: LinearLayout的android:weightSum属性
过程分析:
首先计算出额外空间(可以为负)如果额外空间不为0并且有子View的layout_weight不为0的话按layout_weight分配额外空间:
int delta = widthSize - mTotalLength;
if (delta != 0 && totalWeight > 0.0f) {
...
}
如果LinearLayout设置了weightSum则覆盖子View的layout_weight的和:
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
然后遍历LinearLayout的子元素,如果不为null且Visibility不为GONE的话,取得它的LayoutParams,如果它的layout_weight大于0,根据weightSum与它的weight计算出分配给它的额外空间
if (childExtra > 0) {
int share = (int) (childExtra * delta / weightSum);
weightSum -= childExtra;
delta -= share;
int childWidth = child.getMeasuredWidth() + share;
if (childWidth < 0) {
childWidth = 0;
}
}
网上有解释说layout_weight表示重要程度,表示划分额外空间的优先级,通过代码可以知道这种观点是错误的.layout_weight表示划分的比例,至于当View的layout_width为fill_parent时layout_weight比例相反的问题按我的理解可以作以下解释:
比如说如下XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00ff00"
android:weightSum="0"
android:orientation="horizontal" >
<Button
android:id="@+id/imageViewLoginState"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="1" >
</Button>
<Button
android:id="@+id/imageViewLoginState1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="2" >
</Button>
<Button
android:id="@+id/imageViewLoginState2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="2"
android:text="3" >
</Button>
</LinearLayout>
按一般理解,3个Button的比例应该为1:1:2,但实际情况是这样的:
按我的理解,系统是这样设置按钮的大小的,变量名按前面代码的意义:
假设Container即LinearLayout的宽度为PARENT_WIDTH
三个按钮的宽度都是FILL_PARENT,所以在应用layout_width之前,三个按钮的宽度都为PARENT_WIDTH
所以额外空间 delta = PARENT_WIDTH - 3 * PARENT_WIDTH = -2 * PARENT
因为LinearLayout没有设置android:weightSum(默认为0,设置为0就当没设置吧),所以 mWeightSum = 1 + 1 +2 =4
所以:
第一个按钮的宽度为PARENT_WIDTH + share = PARENT_WIDTH + (layout_weight * delta / mWeightSum) = PARENT_WIDTH + (1 * (-2 * PARENT_WIDTH) /4) = 1 /2 *PARENT_WIDTH
weightSum -= childExtra;(=3)
delta -= share;(=-3/2 * PARENT_WIDTH)
第二个按钮的宽度为PARENT_WIDTH + share = PARENT_WIDTH + (layout_weight * delta / mWeightSum) = PARENT_WIDTH + (1 * (-3 / 2 * PARENT_WIDTH) /3) = 1 /2 *PARENT_WIDTH
weightSum -= childExtra;(=2)
delta -= share;(=-PARENT_WIDTH)
第三个按钮的宽度为PARENT_WIDTH + share = PARENT_WIDTH + (layout_weight * delta / mWeightSum) = PARENT_WIDTH + (2 * (- PARENT_WIDTH) /2) = 0
所以最终的而已就是前两个按钮平分LinearLayout,第三个按钮消失了.
大致过程是这样,但不全对,比如如果上例中LinearLayout的weightSum设置为2的话,前两个按钮的宽度为0,但当计算第三个按钮的宽度是mWeightSum = 0,但layout_weight * delta / mWeightSum无法计算,不知道系统怎么处理的,在我的能力之外了,weightSum为2时的效果图:
weightSum为3时的效果图:
SDK中说明的是,layout_weight表示额外空间怎么划分,要注意额外2字,要有额外的空间才可以将按比例将其分配给设置了layout_weight的子View,所以,如果LinearLayout设置为WRAP_CONTENT的话是没有额外的空间的,layout_weight就没有用处,所只要layout_width不设置为WRAP_CONTENT就行,也可以设置为具体的值,如果值太小的话,额外空间为负,可能压缩子控件,使其大小比XML文件中定义的小,例如:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:background="#00ff00"
android:orientation="horizontal" >
<Button
android:id="@+id/button1"
android:layout_width="60dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="1" >
</Button>
<Button
android:id="@+id/button2"
android:layout_width="60dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="2" >
</Button>
<Button
android:id="@+id/button3"
android:layout_width="60dp"
android:layout_height="fill_parent"
android:layout_weight="2"
android:text="3" >
</Button>
</LinearLayout>
额外空间 delta = 100- 3 * 60 = -80
mWeightSum = 1 + 1 +2 =4
所以:
第一个按钮的宽度为60+ share = 60 + (layout_weight * delta / mWeightSum) = 60 + (1 * (-80) /4) = 40
weightSum -= childExtra;(=3)
delta -= share;(=-60)
第二个按钮的宽度为60 + share = 60 + (layout_weight * delta / mWeightSum) = 60 + (1 * (-60) /3) = 40
weightSum -= childExtra;(=2)
delta -= share;(=-40)
第三个按钮的宽度为60 + share = 60 + (layout_weight * delta / mWeightSum) = 60 + (2 * (-40) /2) = 20
效果图:
以下代码也说明了layout_weight表示额外空间的分配:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:background="#00ff00"
android:orientation="horizontal" >
<Button
android:id="@+id/button1"
android:layout_width="60dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="1" >
</Button>
<Button
android:id="@+id/button2"
android:layout_width="40dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="2" >
</Button>
</LinearLayout>
额外空间为100,所以Button1的宽度为60+100/2=110,Button2的宽度为40+100/2=90
SDK中的解释
Indicates how much of the extra space in the LinearLayout will be allocated to the view associated with these LayoutParams. Specify 0 if the view should not be stretched. Otherwise the extra pixels will be pro-rated among all views whose weight is greater than 0.
重点有两个,一个是layout_weight表示LinearLayout中额外空间的划分(可能扩展应用layout_weight前的大小也可能压缩),另一个是按比例.
以下说的都以 android:orientation="horizontal" 为例
看了一下源码,虽说不太懂,但了解了下大概意思,按照自己的理解总结一下,直接写一下简化的代码吧(下面的代码是LinearLayout源文件中一部分的精简,变量名称含义可能不准确,为叙述方便暂作此解释):
//Either expand children with weight to take up available space or
// shrink them if they extend beyond our current bounds
int delta = widthSize - mTotalLength;
if (delta != 0 && totalWeight > 0.0f) {
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
if (child == null || child.getVisibility() == View.GONE) {
continue;
}
final LinearLayout.LayoutParams lp =
(LinearLayout.LayoutParams) child.getLayoutParams();
float childExtra = lp.weight;
if (childExtra > 0) {
int share = (int) (childExtra * delta / weightSum);
weightSum -= childExtra;
delta -= share;
int childWidth = child.getMeasuredWidth() + share;
if (childWidth < 0) {
childWidth = 0;
}
}
}
}
变量含义
widthSize: LinearLayout的宽度
mTotalLength: 所有子View的宽度的和(还没用考虑layout_weight)
totalWeight: 所有子View的layout_weight的和
mWeihtSUm: LinearLayout的android:weightSum属性
过程分析:
首先计算出额外空间(可以为负)如果额外空间不为0并且有子View的layout_weight不为0的话按layout_weight分配额外空间:
int delta = widthSize - mTotalLength;
if (delta != 0 && totalWeight > 0.0f) {
...
}
如果LinearLayout设置了weightSum则覆盖子View的layout_weight的和:
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
然后遍历LinearLayout的子元素,如果不为null且Visibility不为GONE的话,取得它的LayoutParams,如果它的layout_weight大于0,根据weightSum与它的weight计算出分配给它的额外空间
if (childExtra > 0) {
int share = (int) (childExtra * delta / weightSum);
weightSum -= childExtra;
delta -= share;
int childWidth = child.getMeasuredWidth() + share;
if (childWidth < 0) {
childWidth = 0;
}
}
网上有解释说layout_weight表示重要程度,表示划分额外空间的优先级,通过代码可以知道这种观点是错误的.layout_weight表示划分的比例,至于当View的layout_width为fill_parent时layout_weight比例相反的问题按我的理解可以作以下解释:
比如说如下XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00ff00"
android:weightSum="0"
android:orientation="horizontal" >
<Button
android:id="@+id/imageViewLoginState"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="1" >
</Button>
<Button
android:id="@+id/imageViewLoginState1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="2" >
</Button>
<Button
android:id="@+id/imageViewLoginState2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="2"
android:text="3" >
</Button>
</LinearLayout>
按一般理解,3个Button的比例应该为1:1:2,但实际情况是这样的:
按我的理解,系统是这样设置按钮的大小的,变量名按前面代码的意义:
假设Container即LinearLayout的宽度为PARENT_WIDTH
三个按钮的宽度都是FILL_PARENT,所以在应用layout_width之前,三个按钮的宽度都为PARENT_WIDTH
所以额外空间 delta = PARENT_WIDTH - 3 * PARENT_WIDTH = -2 * PARENT
因为LinearLayout没有设置android:weightSum(默认为0,设置为0就当没设置吧),所以 mWeightSum = 1 + 1 +2 =4
所以:
第一个按钮的宽度为PARENT_WIDTH + share = PARENT_WIDTH + (layout_weight * delta / mWeightSum) = PARENT_WIDTH + (1 * (-2 * PARENT_WIDTH) /4) = 1 /2 *PARENT_WIDTH
weightSum -= childExtra;(=3)
delta -= share;(=-3/2 * PARENT_WIDTH)
第二个按钮的宽度为PARENT_WIDTH + share = PARENT_WIDTH + (layout_weight * delta / mWeightSum) = PARENT_WIDTH + (1 * (-3 / 2 * PARENT_WIDTH) /3) = 1 /2 *PARENT_WIDTH
weightSum -= childExtra;(=2)
delta -= share;(=-PARENT_WIDTH)
第三个按钮的宽度为PARENT_WIDTH + share = PARENT_WIDTH + (layout_weight * delta / mWeightSum) = PARENT_WIDTH + (2 * (- PARENT_WIDTH) /2) = 0
所以最终的而已就是前两个按钮平分LinearLayout,第三个按钮消失了.
大致过程是这样,但不全对,比如如果上例中LinearLayout的weightSum设置为2的话,前两个按钮的宽度为0,但当计算第三个按钮的宽度是mWeightSum = 0,但layout_weight * delta / mWeightSum无法计算,不知道系统怎么处理的,在我的能力之外了,weightSum为2时的效果图:
weightSum为3时的效果图:
SDK中说明的是,layout_weight表示额外空间怎么划分,要注意额外2字,要有额外的空间才可以将按比例将其分配给设置了layout_weight的子View,所以,如果LinearLayout设置为WRAP_CONTENT的话是没有额外的空间的,layout_weight就没有用处,所只要layout_width不设置为WRAP_CONTENT就行,也可以设置为具体的值,如果值太小的话,额外空间为负,可能压缩子控件,使其大小比XML文件中定义的小,例如:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:background="#00ff00"
android:orientation="horizontal" >
<Button
android:id="@+id/button1"
android:layout_width="60dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="1" >
</Button>
<Button
android:id="@+id/button2"
android:layout_width="60dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="2" >
</Button>
<Button
android:id="@+id/button3"
android:layout_width="60dp"
android:layout_height="fill_parent"
android:layout_weight="2"
android:text="3" >
</Button>
</LinearLayout>
额外空间 delta = 100- 3 * 60 = -80
mWeightSum = 1 + 1 +2 =4
所以:
第一个按钮的宽度为60+ share = 60 + (layout_weight * delta / mWeightSum) = 60 + (1 * (-80) /4) = 40
weightSum -= childExtra;(=3)
delta -= share;(=-60)
第二个按钮的宽度为60 + share = 60 + (layout_weight * delta / mWeightSum) = 60 + (1 * (-60) /3) = 40
weightSum -= childExtra;(=2)
delta -= share;(=-40)
第三个按钮的宽度为60 + share = 60 + (layout_weight * delta / mWeightSum) = 60 + (2 * (-40) /2) = 20
效果图:
以下代码也说明了layout_weight表示额外空间的分配:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:background="#00ff00"
android:orientation="horizontal" >
<Button
android:id="@+id/button1"
android:layout_width="60dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="1" >
</Button>
<Button
android:id="@+id/button2"
android:layout_width="40dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="2" >
</Button>
</LinearLayout>
额外空间为100,所以Button1的宽度为60+100/2=110,Button2的宽度为40+100/2=90
发表评论
-
Android SDK下载速度慢无法更新?使用国内镜像站加速
2016-01-29 18:18 693https://blog.kuoruan.com/24.htm ... -
探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法
2014-08-01 12:02 367原文地址:http://blog.zhourunsheng.c ... -
关于ViewPager和Fragment
2014-07-07 14:18 982原文地址:http://www.cnblogs.com/iho ... -
Android移动操作系统的脆弱性分类研究
2014-03-18 14:46 584下载地址:http://www.paper.edu.cn/re ... -
Android实战技巧:深入解析AsyncTask
2014-03-06 11:21 317原文地址:http://blog.csdn ... -
Ubuntu android真机调试
2014-03-06 11:01 419关闭adb服务,切换到root,重启adb服务,离开root ... -
64位Ubuntu配置android环境报错(...adb": error=2, 没有那个文件或目录)
2014-02-07 13:29 561原文地址:http://blog.csdn.net/jayho ... -
【Android 声音处理】MediaPlayer和SoundPool
2014-01-14 17:08 1865原文地址:http://blog.sina ... -
Android自定义组件之一:View详解
2013-07-15 16:08 734原文地址:http://www.eoeandroid.com/ ... -
Android中error inflating class fragment
2013-06-19 17:21 1051原文地址:http://blog.csdn.net/qp120 ... -
拿来主义Android优秀开源项目
2013-06-05 11:57 844http://dengzhangtao.iteye.com/b ... -
android sqlite db-journal文件产生原因及说明
2013-06-05 11:37 3503原文地址:http://blog.csdn.net/chthq ... -
Android系统自带Camera方向判别
2013-05-22 16:40 629使用了OrientationEventListener, 也就 ... -
android onTouchEvent和setOnTouchListener中onTouch的区别
2013-03-27 10:35 677原文地址:http://blog.csdn ... -
Android源码编译整理总结
2013-01-08 11:37 654原文地址:http://www.cnblogs.com/hoj ... -
安卓图表引擎AChartEngine(一) - 简介
2012-12-20 17:47 914原文地址:http://blog.csdn.net/lk_bl ... -
微技巧:Android手机隐藏指令大全
2012-12-07 11:36 728原文地址:http://news.xinhuanet.com/ ... -
自定义控件(attrs定义属性的使用)
2012-12-04 11:38 1119这里为了演示使用自定义变量,字体大小改用自定义的属性。 首先 ... -
二进制在数学中的妙用
2012-11-14 15:50 771原文地址:http://blog.csdn.net/hackb ... -
国外程序员推荐:每个程序员都应读的书
2012-11-06 10:58 767原文地址:http://blog.jobbole.com/58 ...
相关推荐
为什么有时候像android:layout_marginBottom等变量的赋值为负数? 例如如下代码: android:orientation="vertical" android:id="@id/Widget_2X4_frame" android:layout_width="fill_parent" android:...
点对点 Android_Layout_之_RelativeLayout_代码实现相对布局 使用
android:layout_gravity 属性详细解读
用Eclipse加载项目工程 <LinearLayout xmlns:android=... android:layout_weight="0.66" android:background="@drawable/blue_bg" android:orientation="vertical" > android:layout
-<LinearLayout android:background="@drawable/aaa" android:weightSum="1" android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android=...
-<LinearLayout android:background="@drawable/aaa" android:weightSum="1" android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android=...
layout_gravity 在 线性布局 和 帧布局 中的应用 通过代码 直观的展示 layout_gravity 和 gravity 的区别
NULL 博文链接:https://trylovecatch.iteye.com/blog/1195121
android:layout_weight="1" android:id="@+id/vp" android:layout_width="match_parent" android:layout_height="0dp"></android.support.v4.view.ViewPager> android:paddingTop="10dp" android:background...
android:layout_weight="1" android:orientation="horizontal"> android:id="@+id/tv_solid_number" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="本次上架...
layout_weight的作用是设置子空间在LinearLayout的重要度(控件的大小比重)。layout_weight的值越低,则控件越重要,下面为大家介绍下具体的使用方法
android:layout_weight="1" android:layout_height="wrap_content" android:text="行1列2" /> <TextView android:layout_width="wrap_content" android:layout_weight="1" android:layout_height="wrap_content...
android:layout_weight="1" android:src="@drawable/pbg" android:scaleType="centerCrop"/> android:id="@+id/m3" android:layout_margin= "2dp" android:layout_width="60dp" android:layout_height=...
– android:gravity设置了按钮上面的文字的显示位置,而android:layout_gravity设置了按钮在布局中的显示位置。–><LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android” android:...
android_layout属性大全,包括layou的各种属性的汉语意思.方便查找对应个属性
Android中gravity与layout_gravity的区别
android:layout_width= match_parent android:layout_height= wrap_content > <Button android:layout_width= match_parent android:layout_height= wrap_content android:singleLine= true />...
android:layout_centerHrizontal 水平居中 android:layout_centerVertical 垂直居中 android:layout_centerInparent 相对于父元素完全居中 android:layout_alignParentBottom 贴紧父元素的下边缘 android:layout_...
我用的是HorizontalScrollView来实现水平条的滚动,按钮的背景宽度和图片的一致,以免被拉伸,main.xml的配置如下: <LinearLayout xmlns:android=... android:layout_weight="1" >
Android支持多屏幕机制即用为当前设备屏幕提供一种合适的方式来共同管理并解析应用资源。本文就介绍了4中Android屏幕自适应解决方案。...传统的layout_weight使用方法是将当前控件的layout_width和layout_