屏幕适配那点事

前言
做移动开发很定要碰到适配问题,过去android需要,现在ios也需要,今天来谈谈Android机型上一般适配问题该如何处理。

在Android适配的主要是因为众多的手机型号,尺寸分辨率大家都不统一,就目前已经出现的可以分为LDPI, MDPI, HDPI, XHDPI, XXHDPI, XXXHDPI,这个区分很简单不是看手机屏幕尺寸而是看dpi,也就是像素密度。

Android以MDPI作为基准,那么众多dpi之间的关系是这样的


所以如果公司用MDPI的设计图为标准,那么在适配HDPI时,需要的图片资源一般是1.5倍长宽,注意.9图除外,我们通常把.9图和xml drawable都作为是全分辨率的资源单独放在res/drawable下面,其他的图片按照dpi对应放到res下面的drawable-mdpi, drawable-hdpi, drawable-xhpi, drawable-xxdpi,细心的你也许会发现刚刚不是说了还有LDPI么,为什么没有对应的文件夹,其实是这样的,Android建议我们不要单独设计ldpi的资源图片,系统会自动把最接近hdpi的图片缩放作为ldpi设备的资源,具体策略是这样的:HDPI的资源缩小到原来的1/2,所以ldp相对mdpi的比例关系是0.75,所有的dpi之间的关系都用整整数表示的话关系就是1:2:3:4:6:8,由于通常不考虑ldpi,所关系又可以写成2:3:4:6:8.

之前讲的这些关系都反应在图片之前的px关系,现在我们抛开图片px大小,在编码的时候,我们一般说的大小就是dp和sp,dp指的是长宽,sp指的是字体来说。

我们已经知道mdpi是android的基准,自然容易想到dp就是mdpi而言的,所以一个48x48dp的图片在mdpi下面对应48x48px,在hdpi下对应72x72px,依次类推我就不写了。

写到这我们基本把手机适配的本质讲完了,下面接着讲一下如何确定某款机型属于哪个范畴,如上图基本上160dpi,240dpi,320dpi,480dpi,640dpi,这些数字可以有一定的浮动,只要是响应指的左右都算是该dpi的,如果经验丰富熟悉个种手机,你可以很快知道一般720x1280的对应的是xhdpi,480x800或854对应的是hdpi,当然如果你不知道也没问题,可用代码来检车某款手机的dpi,

手机的屏幕参数信息都封装在DisplayMetrics里面,我们可以这样获取

float density = getResources().getDisplayMetrics().density;

int dpi = getResources().getDisplayMetrics().densityDpi;

int widthpx = getResources().getDisplayMetrics().heightPixels;

int heightpx = getResources().getDisplayMetrics().widthPixels;

Log.d("DPI", "density=" + density + ", dpi=" + dpi + ", widthpx=" + widthpx + ", heightpx=" + heightpx);

这样执行完毕我们可以清楚的知道这些重要的信息,比如huawei P6的参数应该是这样的:DPI﹕ density=2.0, dpi=320, widthpx=1184, heightpx=720

上面这些事必须掌握的适配知识,但是光靠dpi并不能解决所有适配问题,比如你有一个pad,尺寸很大有7inch,但是分辨率去很低只有480x800,这种情况就需要另外考虑,应为他的dpi实际是很低的,但是显示空间又大,如果直接用手机上显示的资源布局,那么一定会看起来非常的模糊,所以一般针对pad我们可能会需要专门的布局来利用大空间,比如在手机上我们是单页的,在pad上可以用左右两页同时显示,最经典的就是gmail,左侧标签栏,右侧信息detail。那这样做的目的无非就是说让本来显示48dp的东西在pad上不那么显示,重新调节到合适的大小,既不显得过大模糊,又充分利用了布局。

还有一些零碎的适配技巧就需要在开发中具体问题具体分析了,That's all.



一、引言

  Android的开源使厂商无需自行研发OS,大大降低了研发、生产的成本,使得Android平板品牌如雨后春笋般爆发,山寨机厂商们似乎又找到了一丝希望。与此同时带来的是广大开发者的苦不堪言,各种神奇的小板儿考验着app的兼容性,各种定制的rom不经意间就让app崩溃,光是界面上的调整就已经够你喝一壶了,是不?

二、适配可行性

  早在Android设计之初就考虑到了这一点,为了让app适应标准or山寨屏幕,google已经有一套成熟的解决方案。其中,有这么几个指标需要注意:

  (1)屏幕尺寸:单位inch,指的是屏幕对角线长度。

  (2)屏幕密度:单位dpi,指的是每inch上可以显示多少像素点即px。

  (3)屏幕分辨率:单位px * px,指的是一屏显示多少像素点。

  (4)屏幕无关像素:单位dp/dip,指的是自适应屏幕密度的像素,用于指定控件宽高。

  (5)刻度无关像素:单位sp,指的是自适应字体的像素,用于指定文字大小。

  以我自己的Haier W910超级战舰(宽高比16:9)为例,上述单位的换算如下:

  已知数据:屏幕尺寸4.5, 分辨率1280 * 720, 屏幕密度320

  (1)16:9的4.5寸屏幕由勾股定理计算其高约为3.9寸,宽约为2.2寸

  (2)则竖向dpi为1280 / 3.9 ≈ 328, 横向dpi为720 / 2.2 ≈ 327

  (3)工业上切割液晶板时取整为320

   那么既然dpi是自适应屏幕密度的,与px之间又是如何换算呢:

  120dpi(ldpi低密度屏)       1dp = 0.75px        (由于像素点是物理点,所以用2个像素点来显示3个dp的内容)

  160dpi(mdpi中密度屏)     1dp = 1px

  213dpi(tvdpi电视密度屏)  1dp = 1.33px

  240dpi(hdpi高密度屏)      1dp = 1.5px

  320dpi(xhdpi极高密度屏)   1dp = 2px

  由上述分析结果可知,控件使用dp,文字使用sp即可满足自适应的需求。

三、适配方案

  根据目前的调查,在市面上的平板,基本上属于mdpi和hdpi的,少数属于tvdpi(如google出的nexus7),所以我们选择这三种密度考虑适配;此外手机应用大多数都是竖屏使用,但平板作为娱乐性的一款产品,横竖屏均有使用的时候,所以我们还需要考虑到屏幕状态进行适配;最后考虑到有的rom会将虚拟键计算到屏幕尺寸里,还要考虑到虚拟键所占用的长宽。

  那么如何根据这三个属性来进行适配呢?Android在资源文件values用文件名的方式提供了限定符可以帮助我们判断上述情况,限定符(mdpi,tvdpi,hdpi)可以帮助我们判断屏幕密度,限定符(land,port)可以帮助我们区分屏幕横竖屏状态,而限定符(1024x600...)可以适配计算虚拟键或者不计算虚拟键的屏幕,限定符的详细说明请参见Android SDK文档中开发者指南的Supporting Multiple Screens话题。

  最终适配文件夹如下图所示:

  

  注1:分辨率限定符的匹配是向下匹配,如果没有values-land-mdpi-1024x552,比如,分辨率values-land-mdpi-1024x600的屏幕,当rom不把虚拟键计算到屏幕尺寸时,实际显示的屏幕应该是values-land-mdpi-1024x552,无法适配到values-land-mdpi-1024x600,那这样就可能适配到下一级,比如values-land-mdpi-800x480,但是现在的平板已经没有这么低的分辨率了,所以是配到无限定符的values-mdpi里,造成界面显示上的瑕疵。

  注2:由于分辨率限定符的匹配是向下匹配,所以如果有非主流mdpi屏幕不能精确适配到上述指定值时,values-mdpi至少可以保证app运行时不至于崩溃,同理values可以保证ldpi屏幕的平板不会因生成view而又取不到相应值而崩溃。


你可能感兴趣的:(屏幕适配那点事)