从上面的布局中可以看到,同样是1080P的手机,差异是比较明显的。在这种情况下,我们的UI可能需要做一些微调甚至单独适配。
第二个问题,这种方式无法快速高效的把设计师的设计稿实现到布局代码中,通过dp直接适配,我们只能让UI基本适配不同的手机,但是在设计图和UI代码之间的鸿沟,dp是无法解决的,因为dp不是真实像素。而且,设计稿的宽高往往和Android的手机真实宽高差别极大,以我们的设计稿为例,设计稿的宽高是375px750px,而真实手机可能普遍是10801920,
那么在日常开发中我们是怎么跨过这个鸿沟的呢?基本都是通过百分比啊,或者通过估算,或者设定一个规范值等等。总之,当我们拿到设计稿的时候,设计稿的ImageView是128px128px,当我们在编写layout文件的时候,却不能直接写成128dp128dp。在把设计稿向UI代码转换的过程中,我们需要耗费相当的精力去转换尺寸,这会极大的降低我们的生产力,拉低开发效率。
宽高限定符适配
为了高效的实现UI开发,出现了新的适配方案,我把它称作宽高限定符适配。简单说,就是穷举市面上所有的Android手机的宽高像素值:
设定一个基准的分辨率,其他分辨率都根据这个基准分辨率来计算,在不同的尺寸文件夹内部,根据该尺寸编写对应的dimens文件。
比如以480x320为基准分辨率
- 宽度为320,将任何分辨率的宽度整分为320份,取值为x1-x320
- 高度为480,将任何分辨率的高度整分为480份,取值为y1-y480
那么对于800*480的分辨率的dimens文件来说,
x1=(480/320)*1=1.5px
x2=(480/320)*2=3px
…
这个时候,如果我们的UI设计界面使用的就是基准分辨率,那么我们就可以按照设计稿上的尺寸填写相对应的dimens引用了,而当APP运行在不同分辨率的手机中时,这些系统会根据这些dimens引用去该分辨率的文件夹下面寻找对应的值。这样基本解决了我们的适配问题,而且极大的提升了我们UI开发的效率,
但是这个方案有一个致命的缺陷,那就是需要精准命中才能适配,比如1920x1080的手机就一定要找到1920x1080的限定符,否则就只能用统一的默认的dimens文件了。而使用默认的尺寸的话,UI就很可能变形,简单说,就是容错机制很差。
不过这个方案有一些团队用过,我们可以认为它是一个比较成熟有效的方
公种号:编程进阶路
案了。
UI适配框架(已经停止维护)
鸿洋大佬的适配方案的项目也来自于宽高限定符方案的启发。
使用方法也很简单:
第一步: 在你的项目的AndroidManifest中注明你的设计稿的尺寸。
第二步: 让你的Activity继承自AutoLayoutActivity.
然后我们就可以直接在布局文件里面使用具体的像素值了,比如,设计稿上是96*96,那么我们可以直接写96px,APP运行时,框架会帮助我们根据不同手机的具体尺寸按比例伸缩。
这可以说是一个极好的方案,因为它在宽高限定符适配的基础上更进一步,并且解决了容错机制的问题,可以说完美的达成了开发高效和适配精准的两个要求。
但是我们能够想到,因为框架要在运行时会在onMeasure里面做变换,我们自定义的控件可能会被影响或限制,可能有些特定的控件,需要单独适配,这里面可能存在的暗坑是不可预见的,还有一个比较重要的问题,那就是整个适配工作是有框架完成的,而不是系统完成的,一旦使用这个框架,未来一旦遇到很难解决的问题,替换起来是非常麻烦的,而且项目一旦停止维护,后续的升级就只能靠你自己了,这种代价团队能否承受?当然,它已经停止维护了。
不过仅仅就技术方案而言,不可否认,这是一个很好的开源项目。
小结
讨论的上述几种适配方案都是可以实际用于开发中的比较成熟的方案,而且确实有很多开发者正在使用。不过由于他们各自都存在一些缺陷,所以我们使用了上述方案后还需要花费额外的精力着手解决这些可能存在的缺陷。
那么,是否存在一种相对比较完美,没有明显的缺陷的方案呢?
smallestWidth适配
smallestWidth适配,或者叫sw限定符适配。指的是Android会识别屏幕可用高度和宽度的最小尺寸的dp值(其实就是手机的宽度值),然后根据识别到的结果去资源文件中寻找对应限定符的文件夹下的资源文件。
这种机制和上文提到的宽高限定符适配原理上是一样的,都是系统通过特定的规则来选择对应的文件。
举个例子,小米5的dpi是480,横向像素是1080px,根据px=dp(dpi/160),横向的dp值是1080/(480/160),也就是360dp,系统就会去寻找是否存在value-sw360dp的文件夹以及对应的资源文件。
smallestWidth限定符适配和宽高限定符适配最大的区别在于,前者有很好的容错机制,如果没有value-sw360dp文件夹,系统会向下寻找,比如离360dp最近的只有value-sw350dp,那么Android就会选择value-sw350dp文件夹下面的资源文件。这个特性就完美的解决了上文提到的宽高限定符的容错问题。
这套方案是上述几种方案中最接近完美的方案。 首先,从开发效率上,它不逊色于上述任意一种方案。根据固定的放缩比例,我们基本可以按照UI设计的尺寸不假思索的填写对应的dimens引用。 我们还有以375个像素宽度的设计稿为例,在values-sw360dp文件夹下的diemns文件应该怎么编写呢?这个文件夹下,意味着手机的最小宽度的dp值是360,我们把360dp等分成375等份,每一个设计稿中的像素,大概代表smallestWidth值为360dp的手机中的0.96dp,那么接下来的事情就很简单了,假如设计稿上出现了一个10px*10px的ImageView,那么,我们就可以不假思索的在layout文件中写下对应的尺寸。
而这种diemns引用,在不同的values-swdp文件夹下的数值是不同的,比如values-sw360dp和values-sw400dp,
当系统识别到手机的smallestWidth值时,就会自动去寻找和目标数据最近的资源文件的尺寸。
其次,从稳定性上,它也优于上述方案。原生的dp适配可能会碰到Pixel 2这种有些特别的手机需要单独适配,但是在smallestWidth适配中,通过计算Pixel 2手机的的smallestWidth的值是411,我们只需要生成一个values-sw411dp(或者取整生成values-sw410dp也没问题)就能解决问题。
smallestWidth的适配机制由系统保证,我们只需要针对这套规则生成对应的资源文件即可,不会出现什么难以解决的问题,也根本不会影响我们的业务逻辑代码,而且只要我们生成的资源文件分布合理,,即使对应的smallestWidth值没有找到完全对应的资源文件,它也能向下兼容,寻找最接近的资源文件。
当然,smallestWidth适配方案有一个小问题,那就是它是在Android 3.2 以后引入的,Google的本意是用它来适配平板的布局文件(但是实际上显然用于diemns适配的效果更好),不过目前所有的项目应该最低支持版本应该都是4.0了(糗事百科这么老的项目最低都是4.0哦),所以,这问题其实也不重要了。
评论中还说到了一个缺陷我忘了提,那就是多个dimens文件可能导致apk变大,这是事实,根据生成的dimens文件的覆盖范围和尺寸范围,apk可能会增大300kb-800kb左右,目前糗百的dimens文件大小是406kb,我认为这是可以接受的。
今日头条适配方案(更新)
文章链接,之前确实没有接触过,我简单看了一遍,可以说,这也是相对比较完美的方案,我先简单说一下这个方案的思路,它是通过修改density值,强行把所有不同尺寸分辨率的手机的宽度dp值改成一个统一的值,这样就解决了所有的适配问题。
比如,设计稿宽度是360px,那么开发这边就会把目标dp值设为360dp,在不同的设备中,动态修改density值,从而保证(手机像素宽度)px/density这个值始终是360dp,这样的话,就能保证UI在不同的设备上表现一致了。
这个方案侵入性很低,而且也没有涉及私有API,应该也是极不错的方案,我暂时也想不到强行修改density是否会有其他影响,既然有今日头条的大厂在用,稳定性应当是有保证的。
但是根据我的观察,这套方案对老项目是不太友好的,因为修改了系统的density值之后,整个布局的实际尺寸都会发生改变,如果想要在老项目文件中使用,恐怕整个布局文件中的尺寸都可能要重新按照设计稿修改一遍才行。因此,如果你是在维护或者改造老项目,使用这套方案就要三思了。
福利赠送
一些中高级Android工程师学习资料,需要的可以查看我的【Github】
- 由于篇幅问题,只展示一部分
【Android高级架构师系统学习资料】高级架构师进阶必备——设计思想解读开源框架
第一章、热修复设计
第二章、插件化框架设计
第三章、组件化框架设计
第四章、图片加载框架
第五章、网络访问框架设计
第六章、RXJava 响应式编程框架设计
第七章、IOC 架构设计
第八章、Android 架构组件 Jetpack
关于一些问题
Q: 该适配方案怎么用?
A:点击进入上文的github项目,下载到本地,然后运行该Java工程,会在本地根目录下生成相应的文件,如果需要生成更多尺寸,在DimenTypes 文件中填写你需要的尺寸即可。
Q: 是否有推荐的尺寸?
A 300,320,360,390,411,450,这几个尺寸是比较必要的,然后在其中插入一些其他的尺寸即可,如果不放心,可以在300-450之间,以10为步长生成十几个文件就OK了。
Q:平板适配的问题?
结语
网上高级工程师面试相关文章鱼龙混杂,要么一堆内容,要么内容质量太浅, 鉴于此我整理了上述安卓开发高级工程师面试题以及答案。希望帮助大家顺利进阶为高级工程师。
目前我就职于某大厂安卓高级工程师职位,在当下大环境下也想为安卓工程师出一份力,通过我的技术经验整理了面试经常问的题,答案部分是一篇文章或者几篇文章,都是我认真看过并且觉得不错才整理出来。
大家知道高级工程师不会像刚入门那样被问的问题一句话两句话就能表述清楚,所以我通过过滤好文章来帮助大家理解。
现在都说互联网寒冬,其实只要自身技术能力够强,咱们就不怕!我这边专门针对Android开发工程师整理了一套【Android进阶学习视频】、【全套Android面试秘籍】、【Android知识点PDF】。
大家理解。
[外链图片转存中…(img-uUMTM3A3-1721112529361)]
现在都说互联网寒冬,其实只要自身技术能力够强,咱们就不怕!我这边专门针对Android开发工程师整理了一套【Android进阶学习视频】、【全套Android面试秘籍】、【Android知识点PDF】。