解决多屏幕适配的问题Dimension

开闭原则--可变与不变的分离,且容易定制

应用程序的目的是尽可能做到适用于多种设备,这些设备的配置不尽相同,有些不同的物理尺寸,分辨率.为了达到最佳的适配效果,和最少的代码重复,以及最好的可扩展性,就需要分离资源的使用和资源.用一个统一的资源管理者来管理资源.代码通过资源管理者提供的统一的接口来获取资源.这样对于使用者来讲资源的获取的方式是统一,资源者无需关心如何为不同的设备获取不同的资源.这样就把随不同设备变化而变化的代码降到最低,只有资源管理者需要操心不同的设备相关的不同的资源.

比如:字串的获取和使用.最直接的方式就是直接在代码中使用字面常量.但处理多语言时,这就非常的麻烦,需要代码去判断当前系统语言,然后决定使用哪个!但如果使用资源管理器来获取字串,就把代码耦合降到最低:只有资源管理器需要判断当前系统语言,然后去去相应的字串.其他人则无需要关心.

Android当中也是这样子的,代码通过统一的接口获取系统资源,而由资源管理器来处理设备相关性的问题.

Android的资源里面常见的hdpi等这都是什么意思呢?要理解这些,先要了解一下标准的Graphic
Design中的一些度量和尺寸的

基本的术语和概念:

屏幕尺寸 Screen size

是指屏幕的物理尺寸,度量的方式是以屏幕对角线的长度,单位是英寸(1英寸=2.54厘米).

屏幕尺寸的大与小,通常能决定屏幕究竟能显示多少内容,比如电脑上能显示的区域一般都要比手机要多.

分辨率Resolution

通常以像素为单位,像素的定义为设备能显示的基本单元,比如480x800,或者1024x768,这意思就是说这个屏幕在长度上能显示1024这么多个点,在高度上能显示768个点.分辨率通常用于表示图像的尺寸.但是分辨率不能代表图像的真实物理尺寸.也不能决定在屏幕上显示的物理尺寸.

屏幕密度Density

是指这个屏幕在单位长度上能显示的像素点数,也就是一英寸上能显示的像素点数,计算方式就是分辨率除以物理尺寸.屏幕密度能反应设备的清晰程度.单位通常是PPI(Pixels Per Inch). PPI值越高,证明屏幕的清晰程度越好,能显示的越清楚.比如苹果的Retina系列屏幕,达到了326PPI.人眼的识别能力在300PPI左右,所以达到326时,人眼就无法分辨出像素点了,所以它显示的就更清晰.

有了屏幕密度的概念就可以看到,同样尺寸(分辨率)的图片在高密度的屏幕上显示的物理尺寸就会小(看起来小了),在低密度的屏幕上显示的物理尺寸就会变大(看起来大了).

所以为什么,没有为MBP视网膜屏做适配的软件,比如PS的图标会看起来模糊.因为MBP视网膜屏幕的密度大大提高,是以前的4倍,所以同样尺寸的图片看起来就会比原来小,是原来的1/4,太小了会看不见的,但是这样使用起来是很不方便的.所以Mac系统为了适应新的视网膜屏幕,就必须把图片进行缩放,放大原来的四倍,这样在用户眼中"看起来"(物理尺寸)图片还是那么大!因为图标被拉大了四倍,当然会模糊了!所以,Mac上面的应用,在视网膜之后必须对应用进行专门的优化和适配.

屏幕的长宽比

物理长度与物理宽度的比例.

如何适配不同的屏幕

适配不同的屏幕的目的也就是让应用在所有的系统上体验一致. 这个不同的平台有不同的策略.有些平台仅是以屏幕分辨率为依据.也就是把设备以屏幕分辨率为分类依据.这也是平常所见的VGA一类的名字的来源:

根据不同的屏幕分辨率来区分不同的设备,比如一些常见的名字:

QVGA:       240*320     Quarter VGA 四分之一的意思(1/2 * 1/2 = 1/4)

HVGA:       320*480     Half size VGA 的意思 二分之一(1/2 * 1 = 1/2)

VGA:         480*640      远古时代的电脑显示器的分辨率,其他的都是以此为基础来缩放

WVGA:      480*800      Wide VGA

SVGA:       600*800      Super VGA

等等,关于分辨率的区分可以参考维基百科:Graphics display resolution

那么,有一些的GUI系统就是以分辨率方式来区分不同的资源.

但是,如前面所述,分辨率不能代表屏幕的清晰程度.同样分辨率的图片,或者同样的长度在高密度的屏幕上看起来就会小,在低密度的屏幕上就会变大!因为它的单位是像素.所以,如果以分辨率作为依据来区分资源,那么就必须为所有不同的分辨率设定资源,并且做适配的优化,否则就不会得到好的显示效果!而想一想这工作量会多大!

屏幕密度无关的单位长度

适配不同的屏幕的目的是什么 呢?就是为了能让

1.应用在不同的平台都能正常的显示,也就是把该显示的显示出来,不能太大(低密度上)也不能太小(高密度上)

2. 排版等能够一致.也就是说元素在大尺寸屏幕上(高分辨率)上要大些,在小尺寸屏幕(低分辨率)上要小些

做为懒惰的人类的目的是:用最小的工作量来适配最多的屏幕,那么怎么做到呢?如果能有一个度量单位能随屏幕变化而变化,那多好啊,这样就可以指定一个长度,让设备自己去处理变化的因素.

所以,就出来了一个新的长度单位DIP---Density Independent Pixels,也就是密度无关的一个抽象的单位长度.它不像像素或者Inch之类的固定不变,而是随着设备的密度而变化的.在低密度的设备上它的值很小,而在高密度的屏幕上它的值会变得大些,这样一来,开发者就可以指定一个长度从而适应不同密度的屏幕,以解决低密度屏幕变大,高密度屏幕变小的问题.详细的来讲:比如某一窗口的长度是100DIP,在低密度的屏幕上DIP值,假如说是1pixel,那么长度就变成了100 pixels;而到了高密度屏幕上,DIP可能会变成了1.5
pixel,这样长度就变成了150pixels. 这样就达到了,以不变应万变的目的.而DIP具体取什么值,也是由设备来给出,因为设备知道它自己是什么样的密度.

Android上的适配策略

Android上面如何解决适配不同尺寸(分辨率)和密度的问题呢?它主要是通过以密度分类,再加上分辨率的方式来减化适配不同尺寸屏幕的工作量.

一般来讲,屏幕分辨率越高,清晰度也应该越高,也即其密度也应该越大,否则会看起来很不清楚,比如4寸的屏幕只显示100个像素,这就近距离看电影,或者看投影仪一样,非常的粗糙和不清晰.所以,Android主要是以屏幕密度来区分不同的设备:

高密度:        hdpi       (High dots per inch)

中等密度:    mdpi      (Medium dots per inch)

低密度:        ldpi        (Low dots per inch)

并且布局中推荐使用密度无关单位dip或dp,来作为长度或者宽度的单位.这样,从理论上来讲,开发者只需要做:

1. 为不同的密度屏幕准备图片资源

(图片是没办法的,因为图片的长度和宽度是固定的像素值,不能够随密度变化而变化,可以强行拉伸,但图片会失真.当然也有9 Patch图片可以解决随意拉伸的问题.但普通的图片的长度和宽度是固定的.

2. 用dip作为单位来指定长度或者宽度

就可以适配所有的设备,让布局在所有的屏幕上都得到比较好的显示效果.

当然,现实的生活没有这么完美,各种设备千差万别.但是总体仍可分为这三大类,为这三大类准备好图片后,其他的只要与某一类较接近,即使稍有拉伸或失真,也不太明显,是可以接受的.所以,对于一般性的应用程序,写一个布局文件在layout中,为三种密度准备图片drawable-hdpi, drawable-mdpi, drawable-ldpi,就足以应对80%的设备.

res/

drawable-hdpi/

ic_launcher.png

drawable-mdpi/

ic_launcher.png

drawable-ldpi/

ic_launcher.png

layout/

main.xml

(这里可能有点过时了,因为现在多了xdpi,而且很多设备也是xdpi的.)

但是光以密度屏幕来分类和处理还不够.随着设备的越来越多,以及屏幕尺寸越来越大,还有就是Tablet的出现,又会出现这样的问题:设备的屏幕密度虽然不高,但其分辨率很高.举个简单的例子:iPad2的分辨率是1024x768,iPhone 4 960x640,但是iPhone 4的密度是326ppi,远大于iPad2.但是,无论密度有多高它的屏幕就那么,最多能显示960x640个像素点,一个1024*768的图片在iPad上可以看到全部,而iPhone上只能看到一大半!这也是为什么用iPad来运行iPhone上的应用程序时,只是以屏幕中间的一部分来模拟显示的原因.

对Android来说也是一样的.如此一来,即使相同的dpi,假如其屏幕尺寸非常大,那么为其准备的图片将被拉伸很大或者显示不全.UI元素也会被拉伸很长.这样并不是很好的体验.对于尺寸大的屏幕应该让其显示更多的内容,而不是把一部分元素拉伸很大.所以,很多手机安卓应用如果未经专门适配,在平板上直接使用体验将会是非常差的.

为了解决这样的问题,就还必须以屏幕尺寸来区分设备

主要有四种屏幕尺寸:small, normal, large and xlarge

这主要是配合屏幕密度来一起使用,比如,适配平板的图片:

drawable-xlarge-hdpi/ic_launcher.png

这里就要提到了密度,尺寸和分辨率的对应关系了. 屏幕分辨率是随设备变化最明显的一个,上面的二种分类方法仅是对屏幕进行的大致的一个分类.虽然屏幕分辨率与密度没有直接的关系,但是所有的设备都基本上一致的(约定俗成?):

ldpi            QVGA         240*320           0.8

mdpi          HVGA         320*480           1.0

hdpi           WVGA        480*800           1.5

hdpi           qHD           540*960           1.5

xdpi           WXGA        720*1280          2

对于,如何适配,以及如何提供资源可以阅读官方文档,里面讲的还算详细.http://developer.android.com/guide/topics/resources/providing-resources.html

适配不同屏幕的常见问题

虽然有了上述的策略的方式,但是在实际中还是不够的.因为屏幕尺寸的比例与密度的比例并不一致.举例来说HVGA与WVGA相比,宽度的比例与密度的比例是一致的480/320=1.5.所以说宽度上显示的内容一样多.无需操心.但是高度上面就不一样了.800/480 >1.5,这就造成了什么情况呢,也就是同样的东西缩放了1.5倍以后,对于WVGA还会有相当的屏幕空着.或者如果以WVGA为基准时,放到HVGA上就会显示不全. 在qHD上这个问题会更明显.甚至同样的hdpi的WVGA和qHD都会有问题,qHD能显示的内容要多于WVGA.

使用dimension资源来解决问题

从上面的问题可以看出,密度无关的单位解决不了上面的问题.当然也可以选择为每一分辨率做一布局,但这样又会造成大量的重复工作,因为毕竟布局是相同的,仅是元素的高度或者宽度需要考虑分辨率和屏幕密度.

这时可以把高度或者宽度抽象出来放到一个单独 的资源dimensions中,从而把变化的东西降到最小:

比如某个View的高度:

layout/

main.xml               #  android:layout_height="@dimen/view_height"

values-mdpi

dimensions.xml                 item name="view_height">20dip</item>

values-hdpi

dimensions.xml                                                            30dip

values-hdpi-960x540

dimensions.xml                                                            40dip

还有一点就是,尽可能用相对的值,如wrap_content和fill_parent(or match_parent)它们不是固定的值而是会在具体布局的时候计算出来.

最后,分享一个坑,资源的默认值并不总是values,drawable和layout. 当你分别在values中指定一个值和在values-mdpi中指定一个值,对于其他的类型如hdpi会使用mdpi中的值,而非values中的值.

另外就是,做图片时需要注意尺寸问题

因为图片的尺寸是以像素为单位,而Android应用程序中多以dip或dp为单位,所以就要注意不同密度上它们的对应关系.让像素仁值和用dip换算过后都是整数.举例来讲HVGA上或者mdpi上1个dip就等于1个像素.但到了WVGA或者hdpi上1个dip就是1.5个像素,所以对于WVGA的图片的尺寸的像素值最好能是1.5的倍数.这样就更方便用dip来定义图片的长度的宽度.

其他有用的资料:

1. Support
different Android device configurations with dimension resources

2. Providing Resources

3. 适配特定的分辨率

时间: 2024-11-13 06:57:14

解决多屏幕适配的问题Dimension的相关文章

Android 多屏幕适配 dp和px的关系

一直以来别人经常问我,android的多屏幕适配到底是怎么弄,我也不知道如何讲解清楚,或许自己也是挺迷糊. 以下得出的结论主要是结合官方文档进行分析的https://developer.android.com/guide/practices/screens_support.html android由于碎片化太严重,而导致市面上出现非常多的种类尺寸手机设备,当然也包括非常奇葩的分辨率手机.所以我们在布局的时候使用px作为单位显然不能很好的做到多屏幕的适配.其实在官方文档中有介绍一种解决多屏幕适配的

腾讯优测| 让Android屏幕适配开发更简单-Google百分比布

文/腾讯优测工程师  吴宇焕 腾讯优测优社区干货精选~ 相信开发同学都被安卓设备碎片化的问题折磨过,市面上安卓手机的主流屏幕尺寸种类繁多,给适配造成很大的困难.就算搞定了屏幕尺寸问题,各种分辨率又让人眼花缭乱,当你走出了前面所说的两大坑,很有可能又掉进"屏幕长宽比不同"的陷阱... 说多了都是泪,我就想做一名安静的开发怎么这么难? 经历过无数次跌跌撞撞,我总结出一些经验,想与大家一起分享.已知的屏幕适配方法:(1)按像素比:y/开发时用的屏幕像素=x/用户设备像素(2)按长度:用dip

转: 安卓自动缩放布局,解决屏幕适配问题

转:http://blog.csdn.net/ljh102/article/details/45536293 2015.8.4 更新: 增加参数custom:autoScaleType 设置缩放模式,可以设为“fitWidth”,"fitHeigth" 和 "fitInside".分别代表缩放至宽度匹配,缩放至高度匹配以及缩放至适合容器内部,默认为"fitInside". 做过安卓开发的都知道,屏幕适配是一件非常困难的事情. Google官方的解

Android自定义控件系列八:详解onMeasure()(二)--利用onMeasure测量来实现图片拉伸永不变形,解决屏幕适配问题

上一篇文章详细讲解了一下onMeasure/measure方法在Android自定义控件时的原理和作用,参看博文:Android自定义控件系列七:详解onMeasure()方法中如何测量一个控件尺寸(一),今天就来真正实践一下,让这两个方法大显神威来帮我们搞定图片的屏幕适配问题. 请尊重原创劳动成果,转载请注明出处:http://blog.csdn.net/cyp331203/article/details/45038329,非允许请勿用于商业或盈利用途,违者必究. 使用ImageView会遇到

屏幕适配之百分比方案详解

屏幕适配之百分比方案详解 Android设备碎片化十分严重,在开发过程中的适配工作也非常很繁琐,有关屏幕适配的介绍请看之前的文章屏幕适配. 最近看到DrawerLayout,support v4中提供的类,想到对google提供的这些支持库,自己一点都不熟悉,想着看看Google提供的支持库都有什么内容.结果看着看着在最后忽然看到了Percent Support Library.寻思怎么还百分比呢?仔细一看介绍,我擦,真是太有用了. Percent Support Library The Per

Android 尺寸单位转换和屏幕适配相关

一:Android 屏幕适配 众所周知,Android机型尺寸各种各样,于是屏幕适配就成了Android开发中很重要的一环.Android屏幕适配可能一些开发者都会遇到这样的问题,今天就来分享下屏幕适配,其实Android屏幕适配也可以很简单. 基本概念 Android屏幕适配必须要理解的一些概念: px 是英文单词pixel的缩写,意为像素,屏幕上的点.我们通常所说的分辨率如480X800就是指的像素. 在设计领域中,像素是用来计算数码影像的最小单位.计算机中显示的图像并非连续的线条组成,而是

登录界面、AutoUtils 屏幕适配、自定义Edittext(显示密码可见和一键清空)和 TextInputLayout的使用。

登录界面: AutoUtils自动屏幕适配: AutoUtils屏幕适配使用的方法 : 1.将AutoUtils类复制到要适配的项目中: 2.在程序的入口(清单文件filter):super.onCreate(savedInstanceState);//屏幕适配,这里是以720*1280分辨率为基准的适配AutoUtils.setSize(this, false, 720, 1280); * 这里我们UI是以1920*1280分辨率做图的,并且是横屏显示:AutoUtils.setSize(th

手机卫士13_屏幕适配_异常处理_盈利模式_混淆加密

今天是手机卫士最后一天 1,简易屏幕适配: ①使用线性,相对,帧布局,这三种常用布局在所有设备上几乎可以完整实现,多使用dp,sp,不要使用像素,dp,sp会自动适应屏幕 ②浮动窗体显示的距离问题:它show出来的距离就是像素,所以显示距离不会适应屏幕. 代码里接收的单位一般都是像素. 解决方式:把输入的数字转换成dp单位. 得到像素密度*像素 获得dp数据,根据屏幕实现的像素效果 通过工具类去转换成dp数据DesityUtils 2,应用程序的异常处理: 2.1 alpha版本:小范围的内部测

[转]再谈移动端Web屏幕适配

一个多月前水了一篇移动web屏幕适配方案,当时噼里啪啦的写了一通,自我感觉甚是良好.不过最近又有一些新的想法,和之前的有一些不同. 先说一下淘宝的方案,感觉现在好多的适配方案都是受了它的影响,上周六看了winter在一个会议的分享,讲到了这个方案.现在你谷歌一下移动web适配,绝对可以看到很多类似的,切活动页的童鞋都忍不住试一把.这些方案和我的博客写的其实还是相似的,就是抛弃了那种viewport直接缩放,然后给定html的初始font-size值,使用rem这个单位. 在屏幕的设备像素比上,也