前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >房价都降了!我们聊聊吧。

房价都降了!我们聊聊吧。

作者头像
吴延宝
发布2019-01-09 11:28:26
4260
发布2019-01-09 11:28:26
举报
文章被收录于专栏:中国Android研究院

关注

1

今天呢,我们一起来研究下怎么盖房子。(what!?) 同学们,房价这么贵,该自己学学怎么盖房子了。

大家是不是觉得楼主今天跑题啦,咱先别急,接着往下看。有时候我常想,很多技术的实现方式可能都来源于生活,但又高于生活。拿今天要讲的自定义View来说,其实我们在写自定义View的时候,需要去重写系统为我们设计好的一系列方法(如下所示):

onMeasure -> onLayout -> onDraw 这些方法。

细细一琢磨和盖房子的步骤还是蛮像的。那我们今天就先聊一聊第一步onMeasure

2

盖房子的时候,我们先会确定一块地方,然后用工具量好建房子的地面范围,量好的这块地就是我们可以盖房子的范围。这个过程与我们在自定义View的onMeasure过程是类似的,都是确定一块我们接下来工作的范围。

测量的过程中,我们不单会测量整个房子的大小,我们要综合考虑房子里面的房间格局和大小。我们会测量卧室的大小,测量客厅的大小以及测量厨房的大小等等。

其实这个过程不总是那么顺利的,举个简单的例子:我期望有一个40平的卧室,40平的客厅,30平的厨房。

这么算下来总的需要110平吧,如果我们盖房子的用地能够满足,那我们可以愉快的按照这个期望值进行建造。可是有时候我们并没有那么大用地,我们只有80平的地,根本没法满足这些期望啊。

诶?那这房子还建不建了?建还是要建的,只不过不能完全满足期望而已嘛。我们可以有对卧室、客厅、厨房的美好生活向往嘛,但是美好生活向往的前提建立在伟大的特色社会主义的条件下的。社会主义教导我们“一切得从实际出发,实事求是!”。

建房子我们可以使用社会主义科学理论作为指导,那么在自定义View时,又怎么去指导我们何为实际?什么又是美好向往呢?诶?!对了,正如我们构建自定义View的时候,onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法中的两个参数就是我们科学理论指导嘛,是上级(父类)带给我们的科学指示,你所有对生活的美好向往都必须在这个条件下执行。这样才不会乱套,社会才能更和谐。你看,谷歌也深谙和谐与科学发展之道吧。

3

那么话又说回来了,这个限制到底是如何去限制呢?我们还拿建房子为例。

  • 如果你是一个土豪,根本不用考虑建房子的用地范围,方圆十里都是你的地,呵呵。你说你期望什么40平的卧室,那是事吗?我有这么多地,你想多大卧室都可以!这种模式就是超级富豪式的完全满足你的期望(无限制模式)
  • 有人的是这样的,我虽然有一块地,但是其中一部分我已经做了别的用处,现在卧室剩下30平的可用空间了,所以你的期望多少,我不关心,反正最多只能建30平卧室。(限制上限模式
  • 还有的人是这样的,你必须听父母的。你的父母要求卧室的大小必须是33.333平米,不能多也不能少。父母命不能违啊,我们只能按照33.333平米建造了。(精确模式

诶!?谷歌的工程师看到这一切,深深的吸了一口气,然后缓慢的吐出来,转身回到工位上,盯着想了很久的代码:

代码语言:javascript
复制
protected void onMeasure() {
// TODO 我该咋弄捏?
}

慢慢的嘴角露出一丝笑容,便顺手写下了:

代码语言:javascript
复制
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
        getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}

不错,是建房子给了他灵感,他将建房子限制的三个模式搬到了Android里面。在onMeasure中将上级(父类)的限制通过widthMeasureSpeheightMeasureSpec对宽和高的限制传到子View中,子view通过:

代码语言:javascript
复制
final int specMode = MeasureSpec.getMode(measureSpec);
final int specSize = MeasureSpec.getSize(measureSpec);

上面的方式将限制条件读取出来,其中specMode就是上级的限制模式,specSize就是上级限制的尺寸。然后在我们的自定义View中计算自己的尺寸时,将自己期望的尺寸和父类的要求限制再传入resolveSizeAndState方法中(实际不是直接调用此方法,此处省略),然后在这个方法中,如果读取到限制的的模式是:

  • MeasureSpec.UNSPECIFIED(无限制模式):测量的结果就是自己期望的尺寸 MeasureSpec.AT_MOST(限制上限模式):如果View的期望尺寸小于上限尺寸,使用View的期望尺寸。如果View的尺寸大于或者等于上限尺寸,使用上限尺寸作为测量的结果 MeasureSpec.EXACTLY(精确模式):View的尺寸直接使用上级(父类)要求的尺寸作为测量的结果
代码语言:javascript
复制
public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
        final int specMode = MeasureSpec.getMode(measureSpec);
        final int specSize = MeasureSpec.getSize(measureSpec);
        final int result;
        switch (specMode) {
            case MeasureSpec.AT_MOST:    // 限制上限模式
                if (specSize < size) {
                    result = specSize | MEASURED_STATE_TOO_SMALL;
                } else {
                    result = size;
                }
                break;
            case MeasureSpec.EXACTLY:    // 精确模式
                result = specSize;
                break;
            case MeasureSpec.UNSPECIFIED:// 无限制模式
            default:
                result = size;
        }
        return result | (childMeasuredState & MEASURED_STATE_MASK);
}

做完这些测量以后呢,只需要调用setMeasureDimension将结果保存提交到国土局哦。

End

人民对美好生活的向往,与发展不平衡和不充分就这么愉快的解决了。父子兄弟之间的尺寸之争也被安排的妥妥的,整个社会一片和谐,人民安居乐业。

好了,onMeasure阶段就讲到这里了。下一节onLayout再见。拜拜~

动动小手,关注一下不迷路哦~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-12-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 南京Android部落 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档