适配前与适配后对比情况
还是以iPhone6的设计稿为例子,假如有下面这么一副设计稿,如果不进行任何适配的话,在不同的设备上的显示效果对比如下:
第一个手机就是上文中说到的sw = 375dp的手机,我们可以看到sw为其他值的手机上面,显示效果都不如意。在sw = 411dp和sw = 900dp的设备上,都留有大量的空白空间,而在sw = 360dp的设备上,则有超出屏幕范围的现象。我们适配的目标就是:达到所有设备上显示的效果都和设计稿(sw = 375dp上的效果)一致。
使用calces.screen插件适配后的效果如图所示:
这里有一点需要注意的是,可以看到第三台设备里面的适配还是有点问题,大概留下了1dp左右的白边。这个是pixel 2 XL的模拟器,可以看到,测量出来的sw值应该是411dp的,但是经过笔者的实际测量,发现sw应该是412dp才对。有兴趣的读者可以自己在布局编辑器里面创建一个width为411dp的控件,可以看到在pixel 2 XL设备下也是有大概1dp的白边的。所以这个1dp的误差应该是和设备有关的,这里贴上用calces.screen生成的sw = 411dp的dimens文件的值观大家参考。
53dp 83dp 110dp 137dp 165dp 220dp 274dp 329dp 411dp 31sp 36sp 44sp当sw = 411dp 时,px_375的实际值时411dp,所以这是符合我们的预期转换结果的。
如何引入calces.screen
首先,我们需要引入calces插件,引入的方式很简单:
在项目的build.gradle中添加代码:
//Gradle版本高于2.1的情况下(推荐方案)
plugins {
id “calces.screen” version “1.2.3”
}
//Gradle版本低于2.1的情况下(2.1以上版本也兼容这种方式)
buildscript {
repositories {
maven {
url “https://plugins.gradle.org/m2/”
}
}
dependencies {
classpath “gradle.plugin.com.tangpj.tools:calces:1.2.3”
}
}
在modules的build.gradle中添加代码:
apply plugin: “calces.appconfig”
使用calces.screen适配屏幕
首先,我们需要在res/values/文件夹中创建dimens.xml文件,然后按照设计稿的标尺把需要用到的尺寸写到该文件下。例如:
<?xml version="1.0" encoding="utf-8"?> 48dp 75dp 100dp 125dp 150dp 200dp 250dp 300dp 375dp28sp
32sp
40sp
这就是我们的基准dimens文件。
现在我们只需要把基准尺寸与需要适配的尺寸通过Gradle配置就可以了,例如,上面的例子中,我们需要适配的sw有:320dp, 411dp, 900dp,那么我们需要在modules的build.gradle文件下添加如下代码:
screen{
dimens{
designPx 375
smallesWidths 320,375,411,900
scale BigDecimal.ROUND_UP
auto true
}
}
上面配置信息的对应关系是:
-
designPx:设计稿的sw尺寸(单位px)
-
smallesWidths:需要适配的屏幕sw尺寸(单位dp)
-
scale: 数字取整的方式 因为Android系统只能适配整数单位的dp值,所以我们可以通过scale来配置具体的取正方式。这里直接取BigDecimal提供的round来实现。如果不设置的话,则会生成double类型的dp值(实际使用的时候会丢弃小数位)
-
auto:是否自动生成dimens,当auto为true时,每次build都会重新生成一次适配dimens文件。 如果不设置auto或设置为false的话,可以手动调用gradle任务来生成。 调用命令: /gradlew dimensCovert 也可以直接点击gradle任务执行,方式如下图:
配置完毕后,重新build以下项目就可以看到生成的资源文件了,如下图:
为了不影响编译时间auto建议设置为false,需要的时候再手动启动任务生成适配资源文件。
如何确定我们需要适配什么sw值?
除了自动生成sw外,我们还需要确定,我们的App需要支持那些sw值。最简单的方法就是,先确定我们要支持哪些设备。这里笔者给出一个建议就是,市面上有非常多设备的sw值都是360dp的,所以我们必须要适配360dp的设备。至于其它的设备,我们可以这样来确定,在开发者模式里面找到一项叫做最小宽度的参数,里面的值就是我们需要的sw值。具体如下图:
例如,上面这个是Nexus S的sw值。如果我们不专门适配sw = 384dp的屏幕的话,那么系统就会默认寻找低于384dp的适配资源(所以360dp是一个相对通用的适配值)。当我们拥有测试设备的时候,使用calces.screen适配是非常简单的。那么如果我们不知道没有测试设备呢?(例如有用户反馈,某个设备下的适配有很大问题)
这里给大家推荐一个网站:Device Metrics
这个网站是Material Design的设备参数查找网站,用户在这里直接找到对应设备的尺寸就可以了(之前的方法翻车了,溜了溜了)。
一般情况下,sw为360dp和480dp的屏幕会比较常见,所以我们必须要生成这两套资源,如果需要支持Pad的话,则需要适配sw = 600dp 或 sw = 720dp的屏幕,然后再根据实际情况适配其它sw值的屏幕。
到这里为止,我们就完成了Android基于sw方案的屏幕适配了,非常简单!
但是,本文还没结束,这个插件除了提供自动实现基于sw方案的适配外,还提供了一个杀手级功能:根据配置自动把生成对应分辨率的位图资源。当我们需要适配多种不同屏幕密度的手机的时候,只需要提供一套高清位图资源就可以了,解放你和UI设计师的双手。
calces.screen实现位图自动缩放适配
为不同密度的屏幕提供不同的位图资源是Google官方推荐的屏幕适配做法。这样做的好处是,能使App在不同密度的屏幕上都能达到最好的效果,不会出现在高清屏下出现老年机的显示效果,并且在不同密度的屏幕下都能保持相对稳定的显示效果。下面是位图资源密度对应的比例关系:
密度限定符 | 比例关系 | 说明 |
---|---|---|
ldpi | 0.75 | 适用于低密度屏幕 (~120dpi) 的资源 |
mdpi | 1 | 适用于中密度屏幕 (~160dpi) 的资源(基线密度) |
hdpi | 1.5 | 适用于高密度屏幕 (~240dpi) 的资源 |
xhdpi | 2 | 适用于超高密度屏幕 (~320dpi) 的资源 |
xxhdpi | 3 | 适用于超超高密度屏幕 (~480dpi) 的资源 |
xxxhdpi | 4 | 适用于超超超高密度屏幕 (~640dpi) 的资源。此限定符仅适用于 启动器图标。 |
但是这里会产生一个问题,一般情况下,位图资源是UI设计师提供给我们的。我和很多UI设计师讨论过,他们的方案就是先切一套最高清的图片,然后再根据需要进行缩放,然后提供给工程师使用。
一般情况下,这种做法除了繁琐点也没什么问题。但是如果现在出现了一个情况,就是需要支持更低密度的屏幕呢?这种情况只能让UI设计师再缩放一套密度的位图。那如果某部分位图已经不再使用了,需要删除呢?那工程师需要把其它密度的位图找出来再删除。而且再往工程里面添加新的位图的时候也需要手工添加。
所以一般情况下,UI提供图片资源 —— 工程师使用图片资源这个过程中是纯手工控制的。工作非常繁琐并且没什么意义,而且手动迁移的过程中还非常容易出错(想想如果复制漏了某几个密度的位图资源会是什么画面?)。所以calces.screen还提供了位图管理功能。
calces.screen管理位图
使用Screen的位图缩放功能之前,先和设计师/产品商量好App最高需要支持哪个密度的屏幕。然后设计师以后只需要提供这套密度的位图就可以了。之后我们只需要在modules的build.gradle中进行配置,配置方式如下:
screen{
mipmap{
designDensity “xxxhdpi” //测试用,目前手机屏幕最高只支持到xxhdpi
mipmapDensity ‘xxhdpi’,‘xhdpi’,‘hdpi’,‘mdpi’
auto true
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
最后
我见过很多技术leader在面试的时候,遇到处于迷茫期的大龄程序员,比面试官年龄都大。这些人有一些共同特征:可能工作了7、8年,还是每天重复给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。
其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。
不断奔跑,你就知道学习的意义所在!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。
不断奔跑,你就知道学习的意义所在!