一 写在前面

Android的开源,加速了移动时代的来临,各大厂商纷纷推出自己定制的os,定制的UI,一时间,繁花似锦,各种Android手机,平板如雨后春笋, 与此同时,是广大开发者的苦不堪言,各种神奇的小板儿,见过的,没见过的,时刻考验着app的兼容性,各种定制的rom,不经意间就让app崩溃,光是UI的绘制就会花去不少的时间。

二计量单位

(1)屏幕尺寸:单位inch,指的是屏幕对角线长度。
  (2)屏幕密度:单位dpi,指的是每inch上可以显示多少像素点即px。
  (3)屏幕分辨率:单位px * px,指的是一屏显示多少像素点。
  (4)屏幕无关像素:单位dp/dip,指的是自适应屏幕密度的像素,用于指定控件宽高。
  (5)刻度无关像素:单位sp,指的是自适应字体的像素,用于指定文字大小。
于是有个问题,我们平时在绘制UI的过程中,只知道在需要设置控件宽高的时候,单位是dp/dip,设置字体时,单位是sp,下面讨论一下,问什么要这样处理。
以我的小米2s为例:
屏幕尺寸:4.3inch(宽高比:16:9)
屏幕分辨率:1280*720
就算出屏幕的宽高约为:2inch,3.56inch
垂直方向的dpi为 1280/3.56 = 359.55
水平方向的dpi为 720/2 = 360

通常理论值和实际值还是有区别的,虽然米2s官方称dpi有342,但跑分软件显示是320dpi,这里不去纠结,相信这是工业上切割液晶板时取整为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就完全能够满足自适应的需求,我们就知道了为什么在绘制UI的过程中,Google官方文档建议我们使用dp和sp。

三 适配方案

1. Google官方给出的建议

  • 在分辨率中使用wrap_content, fill_parent,或者dp单位。使用sp单位来定义字体大小。
  • 在manifest文件中声明android:requiresSmallestWidthDp、android:compatibleWidthLimitDp、android:largestWidthLimitDp,限定分辨率。
  • 不使用绝对布局。绝对布局是根据像素点排列的,在项目中推荐使用相对布局。
  • 在代码中尽量不使用硬性定义。使用myView.getWidth()在当前屏幕下得到了10的值,但是可能在另一个屏幕下会得到15的值。所以在代码中使用硬性定义的话,会导致屏幕不适配的问题。
  • 针对不同尺寸和不同密度采用不同的资源。尽管系统可以自动识别屏幕大小并作出资源图片的调整,如果想让图片资源保持不同方向比例一致的话,还是在资源中添加多个资源。如果需要精确地摆放图片位置的话,建议修整图片到合适的大小,并根据图片密度放在不同的文件夹下,例如drawable-mdpi和drawable-ldpi里。


2.其他方案


  • 在布局文件中使用weight来控制位置。将控件的layout中的width、height设置为fill-parent,不要使用wrap-content。因为wrap-content的大小是不固定的。而weight(权重)这个属性很好的解决了这个问题。当包裹在控件外面的Layout的width、height属性都设置为fill-parent时,可以利用weight。即如果控件A设置weight为1,控件B设置weight为2,那么A所占的空间为1/(1+2),B所占的空间为2/(1+2)。这样对任何分辨率下的手机都是合适的。
  • 字体大小的设置。需要在res文件夹中创建一个文件夹,叫做values-1280x720。其中1280x7200是手机屏幕的分辨率,根据手机屏幕的情况做不同的命名,一定要保留res里默认的dimens.xml文件,这样的话可以再屏幕分辨率不适应的情况下找到字体大小。屏幕自适应可能会出现识别错误问题,创建一个drawable文件夹即可。也可以将资源文件放入assets中。
  • 一些比较极端的情况,比如1280x800 1280x768 1280x720,这里可以使用一个兼容性的布局,如果里面含有图片而且对于宽度要求十分精确地话,建议修正图片大小或者做填充处理(在边缘为纯色的情况下将背景填充为和边缘颜色一样的色值即可)。
  • .9.png 图片的使用
  • 通过代码获取屏幕的宽高,进行设置。WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);width= wm.getDefaultDisplay().getWidth();// 屏幕宽度
  • 做一张超大的图片,然后等比例缩小图片,来进行图片的适配。


说明:
分辨率限定符的匹配是向下匹配,如果没有values-land-mdpi-1024x552,无法适配到values-land-mdpi-1024x600,那这样就可能适配到下一级,比如values-land-mdpi-800x480,也可以适配到无限定符的values-mdpi里,造成界面显示上的瑕疵,至少可以保证app运行时不至于崩溃。


更多相关文章

  1. android分辨率(屏幕适配)
  2. Android实现截屏与截长图功能
  3. Android之sp和dip的区别
  4. Android屏幕相关知识
  5. Android(安卓)- 小功能 - Android中dp和px之间进行转换
  6. 监听android屏幕亮、暗、锁和关闭系统动作
  7. 第九章 多语言环境的支持和多屏幕的适配(2)
  8. Android(安卓)AVD创建及设置中各参数详解
  9. android-屏幕适配(一)

随机推荐

  1. Android 制作签名
  2. Activity之生命周期
  3. android对json数据的解析
  4. Android色彩空间像素格式定义及设定
  5. 2011.08.29——— android dip px解析及
  6. [置顶] android sdk 源码解析
  7. SignalR+HTML5实现消息推送及Android通知
  8. Gradle 教程
  9. Android中RadioGroup中RadiaButton不居中
  10. android 开发 GitHub Android Librarys T