前言
Android 的屏幕适配是指适配不同机顶盒 UI 框架层输出的分辨率和 dpi,而不是适配不同分辨率的电视机(电视机的适配交由机顶盒本身完成,和各个应用无关)
之前的文章有介绍过适配相关的问题在和dimens插件,可以前往了解:
背景知识
1、什么是屏幕尺寸、屏幕分辨率、屏幕像素密度?
- 屏幕尺寸是指屏幕对角线的长度。单位是英寸,1英寸=2.54厘米;
- 屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1像素点,一般是纵向像素横向像素,如1280×720;
- 屏幕像素密度是指每英寸上的像素点数,单位是dpi,即“dot per inch”的缩写,像素密度和屏幕尺寸和屏幕分辨率有关;
像素密度公式:
例如:
600*1024的8寸屏幕 | 720*1280的8寸屏幕 |
---|---|
2、什么是dp、dip、dpi、sp、px?之间的关系是什么?
- dip:Density Independent Pixels(密度无关像素)的缩写。以160dpi为基准,1dp=1px
- dp:同dip
- dpi:屏幕像素密度的单位,“dot per inch”的缩写
- px:像素,物理上的绝对单位
- sp:Scale-Independent Pixels的缩写,可以根据文字大小首选项自动进行缩放。Google推荐我们使用12sp以上的大小,通常可以使用12sp,14sp,18sp,22sp,最好不要使用奇数和小数。
如图:
3、什么是mdpi、hdpi、xdpi、xxdpi、xxxdpi?如何计算和区分?
在Google官方开发文档中,说明了 mdpi:hdpi:xhdpi:xxhdpi:xxxhdpi=2:3:4:6:8 的尺寸比例进行缩放。例如,一个图标的大小为48×48dp,表示在mdpi上,实际大小为48×48px,在hdpi像素密度上,实际尺寸为mdpi上的1.5倍,即72×72px,以此类推。
适配前准备工作
1、获取设备分辨率和dpi
可以通过以下代码获取机顶盒UI框架层实际输出的分辨率 (width * height),以及输出的像素密度和像素密度比值
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);//display = getWindowManager().getDefaultDisplay();display.getMetrics(dm)(把屏幕尺寸信息赋值给DisplayMetrics dm);
int width = dm.widthPixels;
int height = dm.heightPixels;
// 屏幕密度(1.0 / 1.5 / 2.0)
float density = dm.density;
// 屏幕密度DPI(160 / 240 / 320)
int densityDpi = dm.densityDpi;
Logger.e("当前设备的分辨率宽=(" + width + "* 高度=" + height + ") densityDpi =" + densityDpi + " density=" + density);
输出:
当前设备的分辨 (率宽=1920*高度=1080) densityDpi =160 density=1.0
2、与UI沟通如何出图?
- 切图应该放哪个 drawable 文件夹下,切多大?
- UI 应该以什么标准出图?
- UI 出的标注图 px 和 dp之间如何转换?
举个例子:
某款盒子通过上述代码获得分辨率为1920*1080 ,DPI为160dpi,盒子连接的是4K的电视分辨率为3840*2160:
- 通过160dpi,根据上表可以得知图片放在
drawable-mdpi
文件夹下- 在只考虑当前设备的情况下,UI应该以盒子的像素1920*1080出图因为,app 在机顶盒上实际输出的像素就只有1920*1080像素,而在4K电视上4K显示效果是机顶盒将系统UI框架的 1920*1080 像素的输出优化放大道 3840 * 2160 像素
- 在160dpi情况下,px与dp是1倍的关系,所以1px = 1dp
适配规则
了解了基本知识和出图标准接下来我们来看一下如何适配:
如果此时我们又有一台设备分辨率为1920*1080 ,DPI为213dpi,盒子连接的是4K的电视分辨率为3840*2160:
我们可以计算一下倍数关系 213/160 = 1.33 ,我们发现并不是上面表格中提供的参数,是个非常奇葩的数字,此时我们计算一下宽度的dp值:1080/1.33=812,所以我们图片和资源文件可以放在values-sw812dp
和drawable-sw812dp
下面。
此时dimens文件中的数值也需要转换,两个相差1.33倍,那么 {现在的dimens数值=(原来的dimens数值 /1.33)}
建议使用打造AS酷炫dimens适配插件 本人的插件,方便做dimens适配哦。
这里只是教大家了一种机型的适配,实际开发中可能会遇到更多奇葩的机型,大家也可以直接使用values-1920x1080
或者values-1920x1080-mdpi
或者values-sw812dp-mdpi
这种组合也可以,道理都是一样的。
详细过程可以参考官方教程屏幕兼容性概览
屏幕配置 | 限定符值 | 说明 |
---|---|---|
smallestWidth | sw<N>dp 示例: sw600dp sw720dp |
屏幕的基本尺寸,由可用屏幕区域的最小尺寸指定。 具体来说,设备的 smallestWidth 是屏幕可用高度和宽度的最小尺寸(您也可以将其视为屏幕的“最小可能宽度”)。无论屏幕的当前方向如何,您均可使用此限定符确保应用 UI 的可用宽度至少为 例如,如果布局要求屏幕区域的最小尺寸始终至少为 600 dp,则可使用此限定符创建布局资源 设备的 smallestWidth 将屏幕装饰元素和系统 UI 考虑在内。例如,如果设备的屏幕上有一些永久性 UI 元素占据沿 smallestWidth 轴的空间,则系统会声明 smallestWidth 小于实际屏幕尺寸,因为这些屏幕像素不适用于您的 UI。 这可替代通用化的屏幕尺寸限定符(小、正常、大、超大), 可让您为 UI 可用的有效尺寸定义不连续的数值。 使用 smallestWidth 定义一般屏幕尺寸很有用,因为宽度 通常是设计布局时的驱动因素。UI 经常会垂直滚动,但 对其水平需要的最小空间具有非常硬性的限制。可用的宽度也是 确定是否对手机使用单窗格布局或是对平板电脑使用多窗格布局 的关键因素。因此,您可能最关注每部 设备上的最小可能宽度。 |
可用屏幕宽度 | w<N>dp 示例: w720dp w1024dp |
指定资源应该使用的最小可用宽度(dp 单位) — 由 这对于确定是否使用多窗格布局往往很有用,因为即使是在 平板电脑设备上,您也通常不希望竖屏像横屏一样 使用多窗格布局。因此,您可以使用此功能指定布局需要的最小宽度,而 无需同时使用屏幕尺寸和方向限定符。 |
可用屏幕高度 | h<N>dp 示例: h720dp h1024dp 等等 |
指定资源应该使用的最小屏幕高度(dp 单位) — 由 使用此方式定义 布局需要的高度很有用,它与使用 |