Android知识点剖析系列:深入了解layout_weight属性

前言

  Android中layout_weight这个属性对于经常捣鼓UI的我们来说,肯定不会陌生。但是我们在真正使用这个属性时,经常会出现一些莫名奇妙的布局效果;如果仅仅知其然而不知其所以然,一些意外的布局效果一定让我们颇为头疼。在本文中,将对layout_weight这个属性详细剖析。

正文

从代码讲起:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Button android:layout_width="match_parent"android:layout_height="wrap_content"android:text="button1"/><Button android:layout_width="match_parent"android:layout_height="wrap_content"android:text="button2"/><Button android:layout_width="match_parent"android:layout_height="wrap_content"android:text="button3"/>
</LinearLayout>

效果图如下:

我们可以发现这三个button并没有将整个屏幕占据,而是根据内容适配大小。

我们在button2里面添加一个属性  android:layout_weight="1" ,发现布局变成这样了:

我们发现这次屏幕被三个button占据了,而且第一个和第三个button还是保持与内容适配大小,而第二个button而占据了剩余屏幕空间。

我们对上面的情况进行讲解:

1、我们只有在button2使用了layout_weight属性,并赋值为1;但是button1和button2并没有使用这个属性,根据API可以知道,他们的layout_weight属性等于0。

2、LinearLayout如果显式包含layout_weight属性时,会measure两次;第一次将正常计算三个button的宽高,第二次将结合layout_weight的值分配剩余的空间。

  通俗点来总结:Android系统先按照你设置的3个Button高度Layout_height=wrap_content,给你分配好他们3个的高度,然后会把剩下来的屏幕空间全部赋给Button2,因为只有他的权重值是1,这也是为什么Button2占了那么大的一块空间。

这么讲解大概大家也对layout_weight属性有了比较清晰的认识了吧。

再来看看下面的代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"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:layout_weight="1"android:text="1"android:background="#ff0000"/><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="2"android:text="2"android:background="#00ff00"/><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="3"android:text="3"android:background="#0000ff"/>
</LinearLayout>

在我们对这三个TextView的layout_width都设置为wrap_content时,我们会得到以下布局:

这个布局很符合我们上面的分析:

系统先给3个TextView分配他们的宽度值wrap_content(宽度足以包含他们的内容1,2,3即可),然后会把剩下来的屏幕空间按照1:2:3的比列分配给3个textview,所以就出现了上面的图像。

如果我们将上面三个TextView的layout_width都设置为match_parent,分别给三个TextView设置他们的Layout_weight为1、2、2的话,会出现一个相反的布局效果:

我们大概可以分辨出,他们所占的宽的比例为3:1:1。这样就出现一个另外一个效果:weight权重越大,控件所占的空间越小。

所以网上就有人这么总结:

在layout_width设置为match_parent的时候,layout_weight所代表的是你的控件要优先尽可能的大,但这个大是有限度的,即match_parent。
在layout_width设置为wrap_content的时候,layout_weight所代表的是你的控件要优先尽可能的小,但这个大是有限度的,即wrap_content。

这是对于这种仅仅记住怎么用而不是为什么这么用的做法,作为一个有追求有理想的程序员是不会苟同的,因为说不定哪天,咱们又忘了口诀,所以我们要从原理上理解为啥是这个样子的。

 

依照上面的理解,这个现象的出现在于layout_width="fill_parent"这个原因导致的;开始下面的分析:

1、系统先给3个TextView分配他们所要的宽度match_parent,也就指定了每一个TextView都是填满他的父控件,这里就是整个屏幕的宽度。

2、由于如果包含layout_width这个属性,LinearLayout将会进行第二次measure,此时将会根据权重分配剩余的空间,在这里剩余空间=1个parent_width-3个parent_width=-2个parent_width (parent_width指的是屏幕宽度 )。

3、第一个TextView的实际所占宽度=parent_width(match_parent的宽度) + 1/5(他所占剩余空间的权重比列) * 剩余空间大小(-2 parent_width)=3/5parent_width

同理第二个TextView的实际所占宽度=parent_width + 2/5*(-2parent_width)=1/5parent_width;

第三个TextView的实际所占宽度=parent_width + 2/5*(-2parent_width)=1/5parent_width

由此我们就可以知道为什么是按3:1:1的这个比例显示了。

 

如果我们将Layout_weight为1、2、3呢?第三个TextView直接消失了有木有!

我们可以按照上面的方法算一次就得出答案了:

1、系统先给3个TextView分配他们所要的宽度match_parent,也就指定了每一个TextView都是填满他的父控件,这里就是整个屏幕的宽度。

2、由于如果包含layout_width这个属性,LinearLayout将会进行第二次measure,此时将会根据权重分配剩余的空间,在这里剩余空间=1个parent_width-3个parent_width=-2个parent_width (parent_width指的是屏幕宽度 )。

3、第一个TextView的实际所占宽度=parent_width(match_parent的宽度) + 1/6(他所占剩余空间的权重比列) * 剩余空间大小(-2 parent_width)=2/3parent_width

同理第二个TextView的实际所占宽度=parent_width + 2/6*(-2parent_width)=1/3parent_width;

第三个TextView的实际所占宽度=parent_width + 3/6*(-2parent_width)=0parent_width

所以三个TextView的显示比例应该为2:1:0,第三个TextView就消失了,因为根据计算,都没有空间可以分配给他了。

看到这里大家都清楚了解了这个计算原理,相信对于设计UI布局有所帮助,对于match_parent和wrap_content混合使用的UI布局也可以通过这个方法进行计算设计。

 

接下来顺带着也给大家说另外一个跟Layout_weight相关的属性:weightSum

顾名思义,就是制定权重的总值,如果不指定weightSum,系统会将各个Layout_weight的值相加得出的总数作为权重总值,当然我们也可以在这里显式指定,这里也方便我们布局所用,我就在下面举一个关于weightSum属性的应用:

 参见这样一个效果,一个总是占据一半屏幕的Button

其实XML代码很简单:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:weightSum="2"android:orientation="horizontal"><Button android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="button"/>
</LinearLayout>

  开发文档中对layout_weight属性的有如下描述:定义weight总和的最大值。如果未指定该值,以所有子视图的layout_weight属性的累加值作为总和的最大值。一个典型的案例是:通过指定子视图的layout_weight属性为0.5,并设置LinearLayout的weightSum属性为1.0,实现子视图占据可用宽度的50。

  从上面的xml中我们可以知道我们设置了weightSum为2,而对于button设置了layout_width为0且layout_weight为1(也就是weightSum的一半),我们就可以得出上面一个效果,使得Button保持占据屏幕的一半,而不用通过硬编码去实现。

 

代码比较简单,这里就不上demo了哈。

 

作者:enjoy风铃
出处:http://www.cnblogs.com/net168/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则下次不给你转载了

转载于:https://www.cnblogs.com/net168/p/4227144.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/259495.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ 中explicit的使用

C提供了关键字explicit&#xff0c;可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。声明为explicit的构造函数不能在隐式转换中使用。 C中&#xff0c; 一个参数的构造函数(或者除了第一个参数外其余参数都有默认值的多参构造函数)&#xff0c; 承担了两个角色。1…

BZOJ 1026 windy数 (数位DP)

题意 区间[A,B]上&#xff0c;总共有多少个不含前导零且相邻两个数字之差至少为2的正整数&#xff1f; 思路 状态设计非常简单&#xff0c;只需要pos、limit和一个前驱数pre就可以了&#xff0c;每次枚举当前位时判断是否与上一位相差2即可。一个需要注意的地方是第一位不用比较…

oracle诊断,Oracle 诊断事件列表

Oracle 诊断事件列表(2013-03-26 18:05:26)标签&#xff1a;oracle诊断事件itORA-10000: controlfile debug event, name control_fileORA-10001: controlfile crash event1ORA-10002: controlfile crash event2ORA-10003: controlfile crash event3ORA-10004: controlfile cra…

考研数学:【以错补错】 降低做题出错率

考研数学&#xff1a;以错补错 降低做题出错率  众所周知&#xff0c;数学需要做题&#xff0c;需要通过做题来巩固掌握&#xff0c;但很多同学却陷入了题海战术&#xff0c;把所有的精力都放在数学练习上&#xff0c;一门心思做题&#xff0c;可几个月下来却没有进展&#x…

treeview右键添加新节点

private void advTree1_MouseDown(object sender, MouseEventArgs e){if (e.Button MouseButtons.Right)//判断你点的是不是右键{Point ClickPoint new Point(e.X, e.Y);Node CurrentNode advTree1.GetNodeAt(ClickPoint);if (CurrentNode ! null)//判断你点的是不是一个节点…

RPM方式安装MySQL5.6

RPM方式安装MySQL5.6 rpm -ivh MySQL-server-5.6.25-1.linux_glibc2.5.x86_64.rpm rpm -ivh MySQL-client-5.6.25-1.linux_glibc2.5.x86_64.rpm rpm -ivh MySQL-devel-5.6.25-1.linux_glibc2.5.x86_64.rpm rpm -ivh MySQL-embedded-5.6.25-1.linux_glibc2.5.x86_64.rpm rpm -iv…

centos7静默搭建oracle11g,Linux静默安装Oracle方法(centos7+oracle11g)

1、 增加虚拟内存ddif/dev/zero of/swapadd bs1024 count2006424mkswap /swapaddswapon /swapadd2、 检查依赖包rpm -q binutils compat-libstdc-33 elfutils-libelf elfutils-libelf-devel gcc gcc-c glibc-2.5 glibc-common glibc-devel glibc-headers ksh libaio libaio-dev…

Ms SQL Server 约束和规则

一、SQL约束 约束定义关于列中允许值的规则&#xff0c;是强制完整性的标准机制。 使用约束优先于使用触发器、规则和默认值。查询优化器也使用约束定义生成高性能的查询执行计划。 1&#xff1a;类型 约束的类型一共分三种 域约束&#xff1a; 涉及一个或多个列&#xf…

Qt 独立运行时伴随CMD命令窗口

用Qt写了一个小软件&#xff0c;在把程序release后&#xff0c;打包分装后&#xff0c;发现程序运行的时候会伴随cmd命令窗口&#xff0c;可把我愁怀了 不过功夫不负有心人&#xff0c;在老师和我网友的帮助下&#xff0c;终于搞完了 CONFIG&#xff1a;指定工程配置和编译参数…

Intellij IDEA 快捷键整理(dyCopy)

原文&#xff1a;http://www.cnblogs.com/tonycody/p/3257601.html【常规】CtrlShift Enter&#xff0c;语句完成“&#xff01;”&#xff0c;否定完成&#xff0c;输入表达式时按 “&#xff01;”键CtrlE&#xff0c;最近的文件CtrlShiftE&#xff0c;最近更改的文件ShiftC…

长竖线及长括号

转载&#xff1a;http://blog.sina.com.cn/s/blog_6005d4af0101861l.html 文章修改中要求把花括号和竖线变长&#xff0c;查了下发现下面的几种方法&#xff1a; 1.花括号“{ }”变长&#xff1a; $\left\{...\right\}$&#xff1b; 或者用 $\Big\{...\Big\}$; 2.竖线“|”变长…

php 加入日志功能,php怎么写一个日志功能的函数

我们要写一个写日志的函数,首先需要了解需求,我们一般怎么用日志函数呢?例如,程序执行到某一步,我希望把这个变量(地址)$user_address的值打印到日志,我们希望日志里是这么写的:xx-xx-xx xx:xx $user_address : 上海市杨浦区xxxxx然后每一条日志都要换行,都有日期时间,假设 函…

Ant简单工程的构建

1.在Ant的官方网站http://ant.apache.org/bindownload.cgi下载Ant最新版本&#xff08;我下载的是apache-ant-1.8.2-bin.zip&#xff09;&#xff0c;Ant无需安装&#xff0c;直接解压后设置环境变量即可。 2.测试Ant是否安装成功&#xff0c;在控制台运行ant命令&#xff0c;出…

MVC学习四

第七节 讲述了增加model中类的属性&#xff0c;由于数据库中已存在表&#xff0c;表中没有存在新加的列&#xff0c;所以可以删除数据库或者在数据库中新增一列&#xff0c;另可以在controller中新增一个数据库初始化的类&#xff0c;并在Global.asax添加初始化数据库的代码 …

mysqlpump 备份文件压缩对比

mysqldump&#xff0c;使用single-transaction&#xff0c;通过管道使用gzip压缩&#xff0c;20G单数据库备份real8m15.291suser8m39.617ssys0m16.675s备份文件1.43Gmysqlpump&#xff0c;4线程&#xff0c;使用single-transaction&#xff0c;通过管道使用gzip压缩&#xff0c…

如何让Latex公式字体变小

转载&#xff1a;http://blog.sina.com.cn/s/blog_5e16f1770100gdxh.html 第一种方法&#xff1a;用比较笨的方法&#xff0c;一个一个公式用 \begin{small} \begin{equation} \ldots \end{equation} \end{small} 第二种方法&#xff1a;定义新的变量环境 在开始 \newenvironme…

php 正则表达式验证金额,php 正则表达式验证数字

非负浮点数(正浮点数 0)&#xff1a;^d(.d)?$正浮点数 ^(([0-9].[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*.[0-9])|([0-9]*[1-9][0-9]*))$非正浮点数(负浮点数 0) ^((-d(.d)?)|(0(.0)?))$负浮点数 ^(-(([0-9].[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*.[0-9])|([0-9]*[1-9]…

ASP.NET MVC:会导致锁定的会话

背景 一直没有意识到会话的访问会导致会话锁定&#xff0c;现在想想这样设计是非常合理的&#xff0c;不过某些情况下这样会导致同一个会话的并发访问非常低&#xff08;只能串行化&#xff09;&#xff0c;好在MS提供了机制让我们控制这种锁。 测试 A页面&#xff1a;缓存写入…

.NET重构(四):窗体继承+模板方法,完美实现组合查询

导读&#xff1a;在机房重构中&#xff0c;有好些个查询都是大同小异&#xff0c;最为显著的就是组合查询了。怎样给自己省事儿&#xff0c;相同的东西能不能重复利用&#xff0c;就成了一个现实的问题。第一遍做机房的时候&#xff0c;使用的更多的是&#xff1a;复制粘贴。学…

github常见操作和常见错误!错误提示:fatal: remote origin already exists.

原文链接&#xff1a;http://blog.csdn.net/dengjianqiang2011/article/details/9260435 如果输入$ git remote add origin gitgithub.com:djqiang&#xff08;github帐号名&#xff09;/gitdemo&#xff08;项目名&#xff09;.git 提示出错信息&#xff1a;fatal: remote or…