专栏名称: 郭霖
Android技术分享平台,每天都有优质技术文章推送。你还可以向公众号投稿,将自己总结的技术心得分享给大家。
目录
相关文章推荐
stormzhang  ·  特斯拉画的饼,圆上了? ·  2 天前  
鸿洋  ·  裁员在家如何保持高效学习 ·  4 天前  
鸿洋  ·  PackageManagerService和 ... ·  5 天前  
鸿洋  ·  2024 了, Insets 你不会还不懂吧? ·  1 周前  
51好读  ›  专栏  ›  郭霖

你真的了解weight和weightSum吗?

郭霖  · 公众号  · android  · 2016-10-19 08:00

正文

今日科技快讯

昨晚7:30,锤子科技在上海梅赛德斯-奔驰文化中心召开了2016年秋季新品发布会。为了给大家带来第一手的资料,我也是熬夜到11点钟,看完了整场发布会后才来写的今天的科技快讯。

在这次发布会上,锤子科技正式推出第三代手机:Smartisan M1 和 M1L,前者为低配小屏版,后者为高配大屏版。这次的锤子手机被粉丝们喻为最有诚意的一代锤子手机,硬件方面被老罗称之为当前最顶配,使用高通骁龙821处理器,配备了高达2300万像素的索尼摄像头,分辨率最高达到2K,最高6G内存以及64GB闪存,支持全网通。

另外在软件方面,锤子科技推出了Smartisan OS 3.0操作系统,其中着实包含了不少令人印象深刻的功能,如Big Bang语义识别、One Step一键分享等等,相信看了发布会直播的朋友们应该对这些功能还是感到颇为震撼的。除此之外,老罗这次竟然还在开源方面发表情怀,为了对谷歌的开源贡献表示感谢,准备将Smartisan OS 3.0操作系统中的One Step等功能也进行开源,引起了现场不小的轰动。

最后,锤子手机的价格方面还算是比较良心的,M1售价2499元,M1L最高配售价2999元。听说这次锤子为了保证货源充足,提前备好了50万台现货手机,但我写到这里时是23:53分,锤子的京东、天猫、还有官网等销售渠道均显示已售罄,看来这次锤子的新品还是相当受欢迎的。

作者简介

本篇来自 胡萝卜小兔 的投稿,给大家分析了 weight 和 weightSum 定义以及使用方法,让你了解更加细节的方面。

胡萝卜小兔 的博客地址:

http://www.jianshu.com/users/17aed505615e

前言

看到本文的标题,很多童鞋会一脸不屑的说,这有什么不了解的。不就是通过weight来给子布局按比例来分配空间嘛!好,这个答案也对也不对。 此时有人会疑惑了,为什么也对也不对? 我先来举两个最常见的例子:

layout_1

layout_2

这两个例子都能实现上图的效果。那么问题来了,这两个方式有什么区别吗? 眼尖的童鞋立马会说:当然有区别,一个 android:layout_width 是 0, 另一个是 wrap_content。 那么这两个有什么区别吗? 为什么实现的效果是一样的? 我还要问一句,真的是一样吗?

如果对这个问题有所疑惑,那么兔子哥将带领大家来深入了解一下weight和weightSum,并通过阅读本篇文章,做到知其然,并且知其所以然。

什么是weight和weightSum

某位伟人曾经说过,要对某个知识点深入了解,最好的切入点就是仔细阅读知识点的定义。至于这位伟人是谁,什么?想不起来了?不用想了,就是这篇博文的作者,兔子哥大人也! ~~~好了,扯了这么多废话!我们还是先步入正题,先看看Google是怎么给 android:layout_weightandroid:weightSum 来定义的:

Layout Weight

LinearLayout also supports assigning a weight to individual children with the android:layout_weight attribute. This attribute assigns an "importance" value to a view in terms of how much space it should occupy on the screen. A larger weight value allows it to expand to fill any remaining space in the parent view. Child views can specify a weight value, and then any remaining space in the view group is assigned to children in the proportion of their declared weight. Default weight is zero.

大体意思就是,android:layout_weight 这个属性代表了一个“重要性”的值,这个值的大小代表了该控件能在屏幕中占据多大的空间。这个值越大,表明该控件可以在父控件中占据较多的“剩余”空间。默认的weight是0。

在这里,大家一定要注意“剩余”两个字!大家往往容易忽略这一点,导致出现了很多问题。举个例子:水平方向布局的父类有三个子类,父类总的宽度是100,子类的宽度分别是10,20,30。 那么 android:layout_weight 这个属性的目的,就是瓜分剩余的 100 - 10 - 20 - 30,也就是剩余的40的使用权。没错! 就是android:layout_weight 这个属性 仅仅决定 哪个子类能瓜分到更多的40的部分!

android:weightSum

Defines the maximum weight sum. If unspecified, the sum is computed by adding the layout_weight of all of the children.

这个就很好理解了,weightSum 定义了 weight 总和的最大值。如果 android:weightSum 没有定义,那么默认值就是通过各个子类的 layout_weight 累加得到。

工作原理

讲了这么多,举个例子来说明一下。

效果如下图:

内部的计算原理是:

Button的宽度 = Button 的 width +  Button的weight *  父布局(LinearLayout)的宽度 / weightSum。

上面的例子,也就是 Button的宽度 =  0 + 0.5 * LinearLayout的宽度 / 1 = 0.5 * LinearLayout的宽度。也就是Button的宽度将占屏幕的一半。

Google官方例子

结合上面的知识再看一下 Google的例子:

https://developer.android.com/guide/topics/ui/layout/linear.html#Weight

可能体会的更加深刻。

首先看效果图:


如果让大家自己来实现这个效果的话,相信很多童鞋会采用相对布局,将send按钮位于屏幕最下方,然后上面的 三个EditText 从上往下依次排列。但是 message 的 EditText 要铺满剩余的空间,这个怎么实现? 有的童鞋会不屑的说了,这有什么难的,把 message 的高度设置 match_parent 并且位于 subject和send之间 即可。代码如下:

但是如果采用本文讲解的 weight 可能会更加的简单。这个布局关键的一点是 message 要铺满 subject与send之间 的区域。问题是如何实现铺满呢? 对了! 本文讲解的 weight 的核心就是瓜分父布局剩余的空间。全部瓜分不就是铺满嘛! 那么代码也就出来了:

着重看一下 message 的布局:

没错,采用了极为巧妙的方法。其他的子布局都不设置 layout_weight, 也就是默认是0 。 那么 message 将获取全部的剩余空间,实现了铺满的效果。

后记

相信阅读到这里的童鞋们,对文章开头的问题应该已经知道答案了。如果还有童鞋不知道答案,可以试着将文章开头的两个Button的内容改一下,一个叫AAAAAAAAA,一个叫B。您再看一下效果,可能就明白了。至于那个也对也不对的问题,“不对”的原因是他们要瓜分的是 剩余 空间。本文止。

更多



如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。

欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号: