几个重要的概念
什么是屏幕尺寸、屏幕分辨率、屏幕像素密度? 什么是dp、dip、dpi、sp、px?他们之间的关系是什么? 什么是mdpi、hdpi、xdpi、xxdpi?如何计算和区分?
屏幕尺寸指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米比如常见的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等。
屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1个像素点。一般以纵向像素横向像素,如19601080。
屏幕像素密度是指每英寸上的像素点数,单位是dpi,即“dot per inch”的缩写。屏幕像素密度与屏幕尺寸和屏幕分辨率有关,在单一变化条件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。
dp dip dpi sp px:
px我们应该是比较熟悉的,前面的分辨率就是用的像素为单位,大多数情况下,比如UI设计会以px作为统一的计量单位,像是获取屏幕宽高等。
dip和dp是一个意思,都是Density Independent Pixels的缩写,即密度无关像素,上面我们说过,dpi是屏幕像素密度,假如一英寸里面有160个像素,这个屏幕的像素密度就是160dpi,那么在这种情况下,dp和px如何换算呢?假设规定以160dpi为基准,1dip=1px,如果密度是320dpi,则1dip=2px,以此类推。假如同样都是画一条320px的线,在480800分辨率手机上显示为2/3屏幕宽度,在320480的手机上则占满了全屏,如果使用dp为单位,在这两种分辨率下,160dp都显示为屏幕一半的长度。所以我们经常使用dp作为单位.
而sp,即scale-independent pixels,与dp类似,但是可以根据文字大小首选项进行放缩,是设置字体大小的御用单位。
mdpi、hdpi、xdpi、xxdpi
其实之前还有个ldpi,但是随着移动设备配置的不断升级,这个像素密度的设备已经很罕见了,所在现在适配时不需考虑。
mdpi、hdpi、xdpi、xxdpi用来修饰用来区分不同像素密度下的图片和dimen值。
那么如何区分呢?标准进行区分:
名称 像素密度范围
mdpi 120dpi~160dpi
hdpi 160dpi~240dpi
xhdpi 240dpi~320dpi
xxhdpi 320dpi~480dpi
xxxhdpi 480dpi~640dpi
在进行开发的时候,我们需要把合适大小的图片放在合适的文件夹里面。下面以图标设计为例进行介绍。
在设计图标时,对于五种主流的像素密度(MDPI、HDPI、XHDPI、XXHDPI 和 XXXHDPI)应按照 2:3:4:6:8 的比例进行缩放。例如,一个启动图标的尺寸为48x48 dp,这表示在 MDPI 的屏幕上其实际尺寸应为 48x48 px,在 HDPI 的屏幕上其实际大小是 MDPI 的 1.5 倍 (72x72 px),在 XDPI 的屏幕上其实际大小是 MDPI 的 2 倍 (96x96 px),依此类推。
下图为图标的各个屏幕密度的对应尺寸
屏幕密度 图标尺寸
mdpi 48x48px
hdpi 72x72px
xhdpi 96x96px
xxhdpi 144x144px
xxxhdpi 192x192px
2.SyberOS适配方案
SyberOS屏幕适配方案主要解决尺寸,图片,及字体的适配.主要设计思路是依据DPI完成对应数据的缩放,以分辨率1920*1080 像素密度为400dpi作为标准,进行适配.最终效果是,在不同终端屏幕上看到的大小是一样的.单位使用dp.同时,为了考虑各程序的兼容,本方案支持应用指定设计稿分辨率及目标像素密度,即dpi…
2.1 确定缩放系数
根据当前设备的实际像素密度与系统标准UI设计稿DPI(或应用自定义设计稿DPI),确定像素密度缩放系数dpiRatio=系统标准DPI或应用自定义DPI/设备实际DPI.缩放系数采用对角线的计算方法.
2.2 确定视图组件尺寸
系统提供视图尺寸函数dp,用于将应用或者系统标准设计像素转为实际设备对应的像素.在标准设计DPI或用户自定义DPI情况下,1dp=1px.然后根据实际系统DPI,实际像素为设计像素*缩放系数.系统不同设备的dpiRatio将px转为对应的dpi设备的像素进行显示适配.
2.3 确定自体尺寸
字体系统中提供了pointSize函数,即pointSize此与设备无关像素的处理方式,但是存在px与dp的转换,比较麻烦,建议使用pixelSize属性设置设计像素字体,系统提供了sp将系统设计像素适配到目标设备的DPI中…
2.4 图片资源夹在
指定图片资源的加载.对于不同屏幕,夹在不同像素的图片,以达到最优效果.目前系统中提供了默认及不同像素密度区间的文件夹,即img系统标准或用户自定义DPI时文件存放地址. img_s是120dpi以下设备图片资源. img_m是160dpi以下图片资源.img_l是240dpi以下图片资源. img_xl是320dpi以下图片资源. img_xxl是480dpi以下图片资源.img_xxxl是640dpi以下图片资源.图片资源都需要放置在res/img*文件夹下,并且添加到系统资源文件中.如果对应文件夹下没有文件,使用默认标准文件夹img下的文件.
通过不同分辨率只是为了尽可能结局适配不同dpi下图片的加载效果.但是实际中依然存在图片加载适配非比例拉升的问题.对于指定宽高尺寸的图片等比例拉伸,只是存在图片清晰度的问题,但对于一些非明确尺寸的图片显示,依然会存在图片拉升的问题,如指定尺寸使用了parent.width或parent.height的情况.同时,还存在相同分辨率,但dpi不同的设备,以及相同dpi但分辨率不同的设备适配问题.典型的,如图片加载横向指定了parent.width,高度指定了具体值400px.这时候就会出现伸缩图片变形的问题.为了解决图片的伸缩问题,可以采用两种方案:
1.使用IMage的fillMode: Image.PreserveAspectCrop,这个会将图片大小按照等比例缩放到填充的尺寸后进行裁剪.这个保证了图片的不变形,但是会剪切掉一部分的图片.可能在放大后剪切导致一些图片内容被裁剪掉.(建议方案)
2.使用BorderImage.这个是用在图片放大场景中.通过设置border的4个边沿,确定缩放的区域.因为其对边角不做缩放,所以可以考虑将图片拉伸变形有影响的部分放在边角区域内,保证图片可以被拉升,但不体现变形.但是如果图片的大小可以覆盖控件的大小,则不会做放大处理.这就会导致图片压缩依然变形的问题(根据实际情况判断使用).
3.具体实施方案
系统提供了适配工具类CEnvironment类(syberos-qt库中).其提供了相关的函数.
同时在syberos-toolkit-core公共控件中注册了env的对象,
3.1 应用自定义基准dpi
设备实际dpi为1中定义的屏幕像素密度这里记作Rdpi,除此之外应用可以自定义自己的基准dpi(基于什么dpi设计的应用)记作Adpi,和系统默认的基准dpi记作Sdpi。假设应用在自己的基准dpi下的宽度为x,在新设备上的宽度记作NX。则根据下面的公式
Rdpi/Adpi∗x=NX
可以获得原有应用在实际设备上宽度。
假如应用没有自定义基准dpi则用系统默认基准Sdpi可以获得应用在新设备上的宽度。
Rdpi/Sdpi∗x=NX
3.2 几个函数
1)dp用于计算尺寸的接口,参数是px单位.
2)sp:用于计算自体的借口,参数是px
3)img是用于获取目标分辨率图像的函数,参数是文件名,且文件必须放置在res/img*的目录并加到资源文件中.
4)应用自定义dpi:initAppDpi,参数是设计稿的目标dpi.
3.3 历史应用dpi方案识别
如果应用使用的新的dpi适配方案,server端和client端可以在窗口创建的时候获得,针对已经使用dpi适配方案的应用,则正常显示就可以。但是针对没有使用dpi适配方案的原有应用,则在窗口管理器中针对应用进行缩放或者根qml中缩放。
3.4 使用方法
1)C++中,可以在pro文件中引入syberos-qt库,然后创建CEnvironment类并进行使用.示例代码如下:
在pro文件中引入syberos-qt库:
CONFIG += link_pkgconfig
PKGCONFIG += syberos-qt
引入并创建CEnviromment类:
#include
…
CEnvironment *env = new CEnvironment(this);
env->dp(32)
…
2)在QML中,导入syberos-toolkit-core插件,并通过http://env.xxx这样的方式引用.示例代码如下:
导入公共组件:
Import com.syberos.basewidgets 2.0
…
env.dp(32)
…
更多SyberOS的文档请浏览:
SyberOS介绍 · SyberOS开发者文档developer.syberos.com