在开发过程中,没有差不多这个概念,差之毫厘谬以千里。
一款好的产品,经过了很多的工序,包括市场调研,产品策划,美工设计,开发测试上线等。每一个环节扣在一起,完美对接才能被用户所接受。
很多开发者,把UI看的不是很重要,但是我觉得恰好相反,UI是一款APP给用户的第一直观感受,如果UI做不好,哪怕是业务逻辑再好,体验再好,最终也只能被用户所抛弃。因为用户不会管你的业务逻辑,他们只会管他们所能看到的,所以一款产品的成功,跟产品的UI是息息相关的。
以下展示几样让开发者头疼的UI效果
其实以上UI效果看似不难,但实际让你去实现它们的交互还是比较复杂的,如果没有很高的UI底子以及丰富的自定义控件经验,基本很难搞定。
所以,当你遇到美工抛给你的难点的时候,你是怎么做的呢?赶紧网上找资源?还是自己去实现?
在互联网行业,别人会称我们为“代码的搬运工”,Why?因为我们的工作往往就是搬运,把一块代码从一个地方搬到另一个地方,周而复始。
那么,搬运完了之后,我们学到了什么?在我们的职业生涯,有没有为我们行业贡献过什么?几乎没有。
在我看来,UI这个问题就映射了我们整个行业的问题。
回到UI的问题上,其实UI难不难,不难,无非就两个东西嘛,View以及ViewGroup,只要你把这两个东西吃透了,UI还有什么是你做不到的呢?但是吃透谈何容易,里面的难点也比较多,比如:
- MeasureSpec测量规则。
- 为什么MeasureSpec要用一个32位的int类型的变量来保存。
- 为什么有时候会测量多次。
- 为什么UI会导致内存抖动。
......
尤其是MeasureSpec的源码这块,基本很少有人能讲的通的,网上的博客都是讲的很浅显,所以这一块要搞懂不是很容易。不过我大致可以跟大家说一下。
MeasureSpec首先它只是一个工具类,它提供了生成测量规则的makeMeasureSpec()方法。在这个方法中,它会通过二进制运算把传进这个方法的Size和mode结合在一起生成一个新的int类型的参数。
如图,在makeMeasureSpec()方法中返回的int类型的参数来源
这里有一个知识点,为什么返回的是int类型的参数?首先我们要明白,二进制运算实际上就是运算这些变量的二进制形态,但是二进制只是在内存中的表现形式,在我们程序里面拿到的都是十进制,因此,运算的时候是执行二进制运行,但是最终返回的值它的十进制。
那么返回的这个int类型的变量到底包含了什么呢。实际上它包含了一个控件的初始尺寸以及测量模式。为什么一个int类型的参数能够包含两个内容呢,所以这里不得不得说谷歌的工程师们还是很厉害的的。有了解过的都知道,一个int类型的参数,在内存中是一个32位的二进制(4个字节,每个字节8位)。所以谷歌的工程师们用这32位的二进制的高两位(前两位)保存测量模式,后三十位保存size,这样的话就可以用一个int变量来保存两样东西了(这里不难发现,所有的测量规则中,这个int参数的本身是多少不重要,因为不会用到,真正用到的是它的二进制)。
如下图:
而且在MeasureSpec里面也有相对应的反向方法,即然可以把mode和size用一个int类型的参数来表示,也可以通过这个int类型的参数把mode和size提取出来,这里对应的方法就是getMode()以及getSize()方法。