The Android Evolution of Supporting Multiple Screens

简短不割,直入正文。iOS最鄙视Android的是什么?乔布斯每场发布会必鄙视Android的是什么?UI!!为什么iOS总是有那么多美轮美奂的界面,而Android却总显的那么苍白无力?主要原因就是Android手机TM屏幕尺寸太多了,各种屏幕尺寸配上各种分辨率,让一大帮程序员对做界面没了兴趣,再加上iOS与生俱来的出色的图形动画性能和乔布斯教主般的吸血光环,又让一大帮程序员做起了iOSGoogle当然意识到了这个问题,在新版本中不断的提升图形性能,发布Android UI规范,在Android 4.0以后加强控制硬件规格,这都为做出漂亮的界面打下了基础,但论使用度和程序员接触最深的,当属一整套的屏幕适配方案。

打做Android UI的第一天起,所有的学习资料都在告诉你,控件定位要用dp,不能用px,但是,这TM是为什么?于是,所有的学习资料又都在告诉你,Android中屏幕被分为了高、中、低等密度以及大、中、小等尺寸,做界面不用考虑分辨率,只需考虑密度,但是,这TM又是为了什么?然后,所有的学习资料就都不说话了。于是,我只能从它们谈论的只言片语中找出历史的正文。

声明:以下信息有部分内容纯属猜测。

早在公元2008年,第一款Android手机横空出世,这就是由HTC出品,T-Mobile定制的T-Mobile G1,搭载3.17英寸,320*480HVGA)分辨率的显示屏,此时的Android还是1.0版本。既然是第一款Android手机,那App的界面当然是按照这个标准来做,个人猜测可能这时候在UI中还是用的px做单位。之后20091Kogan推出了正统的全球第二款Android手机——Agora,使用Android 1.5的系统,但搭载的却是2.5英寸,240*320QVGA)分辨率的显示屏,在加上各种山寨手机,这时问题出现了:分辨率不一样了,而且还有增多的趋势,每个应用得为不同的分辨率发布好几个版本,显然用px定位界面元素已经不适用了,那该用什么来保证一个App在不同的屏幕尺寸下都能运行呢?

其实想一想适配的主要目标是什么,不就是保证不同屏幕上显示的界面元素的百分比相同么。那能直接用百分比来直接指定位置吗?显然不行,首先肯定要考虑到兼容以前的程序,其次用百分比来指定位置也太不准确了。

那我们来从另一个方向来考虑,比如有320*480480*800两种分辨率的屏幕,为了兼容以前的应用,肯定以320*480的屏幕为标准,那我们考虑如果要保持界面元素的百分比不变,从横向上计算,在320*480屏幕上的一个像素,在480*800的屏幕上应该为1.5个像素才能保持比例,因为480/320=1.5,也就是把480分成了320份,每份1.5个像素。同样对于240的屏幕来说,就是0.75。现在一切看起来都很好,貌似在布局时获取一下分辨率然后进行如上的计算就行了,肯定可以保证显示效果是相同的,但是,要注意到我们用的是像素,显示的最小单位,半个像素是没办法显示的,所以只能进行修正:对结果加上0.5再四舍五入,这就使得不同分辨率显示的效果总会有偏差。

然后,我们再来考虑屏幕尺寸。我们知道分辨率和屏幕尺寸是没有关系的,320*480的分辨率可以做在一块3.5英寸的屏幕上,而640*960的分辨率同样可以做在3.5英寸的屏幕上,相似的,320*480的分辨率可以做在3.5英寸的屏幕上,也可以做在3.2英寸的屏幕上。对于在3.5英寸上320*480屏幕上的一个像素,同尺寸640*960的屏幕就要用2个像素,也和上边的运算一样。

现在我们把上边两种情况综合起来考虑,其实用分辨率除以屏幕尺寸计算出单位长度的像素数,就足以计算百分比了,这个单位长度的像素数就是万恶的屏幕密度。

计算方法就是用屏幕对角线的像素数/屏幕对角线的尺寸(也就是屏幕尺寸)。

所以从Android 1.6开始,Google开始使用屏幕密度的概念来定位界面元素。同样,为了兼容以前的程序,肯定要以以前的屏幕密度做为基准,但计算后却发现G1的屏幕密度其实是180,不是官方定义的160,至于原因,可能是对不同屏幕密度取的一个平均值,但更应该注意到,iPhone的屏幕密度就是赤裸裸的160,我好像发现了什么。

采用屏幕密度以后,定位的单位开始使用dp,而不是px,从Android 1.6开始Google定义了三种屏幕密度:120160240。对于160的基准密度屏幕,1dp=1px。而在240的屏幕下,1dp=1.5px

从此,dp就是屏幕适配的第一个维度,开发人员只需在程序中使用dp指定元素位置,其它的操作都由系统自动完成。

目前来看,这个方法对当时的手机来说应该够用了(2.5英寸到3.5英寸左右,横向都是320dp)。但向长远考虑一下,屏幕的尺寸越来越大怎么办。计算一下,480*800的屏幕如果做到5英寸,那屏幕密度就也是160了,根据基准屏幕的定义,此时1dp=1px,也就是横向会有480dp,而不是320dp,这时若运行以前的应用屏幕右侧肯定会有空白。其实我们考虑一下,大屏幕的初衷就是为了显示更多的内容,如果还是按比例来缩放,显示的内容和小屏幕的相同,那大屏幕就没有意义了。所以,Google引入了屏幕适配的第二个维度——屏幕尺寸。于是,就出现了每个屏幕适配教程都会用到的表:

密度

屏幕大小

Low density

(120)ldpi

Medium density

(160)mdpi

High density

(240)hdpi

Small screen

2.5寸到3.2

240x320

 

 

Normal screen

3寸到4.3

240x400

240x432

320x480

480x800

480x854

540x960

Large screen
4
寸到7

480x800

480x854

480x800

480x854

 

Android 1.6开始,Google不仅把屏幕密度分为了高中低三种,还把屏幕尺寸分成了大、小和普通三种。对不同的屏幕尺寸,就可以使用不同的布局文件,如普通尺寸的屏幕就把布局文件放在layout目录中,而大屏幕的布局文件就放在layout-large中,同样小屏幕的布局文件就放在layout-small中,系统会自动根据屏幕尺寸加载对应的布局文件。

但是人们对于大屏幕的追求是无止境的,iPad的推出必然使Android引进更大屏幕的设备,于是在Android 2.3开始,屏幕尺寸增加了超大屏幕(Extra Large Screen)和超高密度(Extra High Density),上表就变成了如今的最终形式:

Low density (120), ldpi

Medium density (160),mdpi

High density (240), hdpi

Extra high density (320),xhdpi

Smallscreen

QVGA (240x320)

480x640

Normalscreen

WQVGA400 (240x400)
WQVGA432 (240x432)

HVGA (320x480)

WVGA800 (480x800)
WVGA854 (480x854)

600x1024

640x960

Largescreen

WVGA800** (480x800)
WVGA854** (480x854)

WVGA800* (480x800)
WVGA854* (480x854)

600x1024

Extra Largescreen

1024x600

WXGA (1280x800)
1024x768
1280x768

1536x1152
1920x1152 
1920x1200

2048x1536
2560x1536 
2560x160

如此,二维布局适配大法最终成型了,此法由两个维度来适配屏幕,横向维度由系统自动控制,纵向维度通过布局文件指定。

在如此完美的方案下,Google还是觉的不够,尤其是在平板上,每一寸的空间对UI都是至关重要的。所以在Android 3.2Google又引入了新的布局限定符:sw<N>dpw<N>dph<N>dpN用来指定dp数,如layout-w720dp,系统会在当前宽度最少为720dp的条件下加载此目录下的资源文件,这比用layout-xlarge-land更精确。

如此,布局文件算是告一段落。但界面上的元素除了控件,更多的恐怕是图片。对同尺寸的图片,放在低密度屏幕上会很大,而放在高密度屏幕上会很小,这明显不符合保持百分比不变的理念。所以,Android会根据设备的屏幕密度,自动放大或缩小的图片,使得在不同密度的屏幕上看起来大小是相似的,这虽然方便,但图片的放大和缩小会造成失真,这对制作漂亮的UI是个嚣张的挑战。所以借鉴布局的做法,Google对图片按照屏幕密度进行了分类,如:drawable-ldpidrawable-mdpidrawable-hdpi等,系统会根据不同的密度加载对应目录下的图片。而对于实在是不想进行缩放的图片,可以放在drawable-nodpi。因为四种屏幕密度是有比例的,所以官方建议图片的比例为3:4:6:8

第二部分对开发人员的建议

借鉴官方的Best Practices,对开发人员在适配中提几点建议:

1、充分利用Layout的特性,比如居中,与其费劲去计算margin,不如用RelativeLayoutcenter来的方便,并且可以适配各种屏幕。

2、充分利用控件的属性,什么wrap_contentfill_parent,能让系统计算的就让系统去计算,尤其是layout_weight,用的适当可以产生很好的适配效果。

3、指定位置一定要用dp,不要用像素值。而且对于不同屏幕需要指定不同位置的情况来说,请使用dimen。因为values也是可以指定屏幕的,如values-normal-hdpi

4、不要使用AbsoluteLayout,这是官方说的。

5、对平板和手机,还是做两个版本吧,就平板所提供的图片资源就不是手机能受的了的。更别说为了适配要建立多少资源目录了。

6、和设计人员多沟通,利用好.9.png的图片,可以节省不少时间和空间。

7、字体大小使用sp

第三部分对设计人员的建议

1、要理解用dp取代px的原因,最好能理解适配中所采用的一般方法。

2、对不同的屏幕密度提供切图,注意要保持比例。

       3、最好能按照屏幕密度为160的尺寸做效果图,这样开发人员在开发过程中可以进行11的比对。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值