Skip to content

Latest commit

 

History

History
47 lines (28 loc) · 5.64 KB

Android-adapt-ued-mark-convert.md

File metadata and controls

47 lines (28 loc) · 5.64 KB

适配基础知识可以参见:《Android屏幕适配全攻略(最权威的官方适配指导)》

如果UED出了一张UI设计图并标注了相应元素的尺寸和间距px值,作为Android开发者,如何在程序中将标注值转换为相应的dp值呢?

##目标效果 要确定转换的方法,首先需要明确转换的效果。

在手机上,我们应当注重的是元素的横向排列,而非纵向排列——元素横向应当等比缩放,纵向可以选择与横向等比缩放或者保持固定尺寸。

元素横向的等比缩放是指:加入手机A的宽度是1080px,屏幕上有一条线的宽度是540px,那么这同样“尺寸”的线在宽度为540px的屏幕上宽度就应该为270px。这也正是Android引入dp的目的:

DP对不同分辨率屏幕的支持

这张图非常经典,但是注意,Button看上去一样大小的前提是:屏幕的宽度是一致的。而现实生活中,手机的宽度往往有差异,因此同一个dp值的元素在这些手机上显示出来的物理尺寸并不一致,但是屏幕截图后在Photoshop上拉至同一个宽度,就可以看出尺寸是同样大小的。

为什么要注重元素的横向显示而非纵向?元素横向等比缩放有助于元素更好的排列,高度与之等比缩放可以使得长宽比越大的手机在纵向上显示更多的元素,从而体现大屏手机的优势,而且手机页面的上下滚动是非常自然的操作,所以,注重元素横向可以使同一个界面在任何手机上体验更好。

##转换方式 确定效果的目的一方面是确立转换目标,一方面也是下面转换的前提:我们将注重元素的横向比例拉伸。

OK,我们看如何转换UED的视觉标注,才能得到合理的dp值。这里需要另外假设很多的变量,含义如下:

  1. 假设UED出的视觉稿宽度是Spx,有一个标注是 B px,UED的这份视觉稿使用的dpi是 P dpi,即一英寸里面有 P 个像素。
  2. 假设我们开发的手机宽度是Apx,屏幕密度是D,即dpi=160D,我们从标注转换过来的值是X,即最终写入程序的是 X dp,即最终屏幕上显示出来的是XD个像素。

基于以上假设和目标,我们想象,将我们写出的界面(为了便于想象,假设标注是用于一个元素的宽度)等比例缩放,和UED出的视觉图重叠,根据效果,此时元素的宽度与UED视觉稿上的宽度应该完全一致。根据假设值,可以得到以下参数:

  1. 设计视觉稿的物理宽度:S/P——记为M;
  2. 设计视觉稿上元素的物理宽度:B/P——记为N;
  3. 实际运行程序的手机屏幕物理宽度:A/160D——记为X;
  4. 实际运行程序的手机上元素的物理宽度: XD/160D——记为Y;

根据目标,应该有 N/Y=M/X ,化简后可以得到 X = AB/DS——这就是我们应当正确写入程序的dp值,它是一个与程序实际运行手机宽度、屏幕密度、视觉稿设计所用宽度以及标注值相关的变量。

##思考 根据上面的公式,实验结果是符合的。但是这四个变量的组合非常奇怪,如果说最终值与标注值相关,那是理所当然的,但是怎么会和屏幕密度有关(dp值不就是用于解决这个问题么?),还和视觉稿设计所用宽度、手机宽度相关?手机宽度还是一个不确定值!

实际上视觉稿所用宽度并不会影响最终的计算,因为这个值的比例变化会和标注值相抵消。设想设计师在一个1000px宽度的视觉稿上画一条占满半屏幕的线,需要500px,因此他的标注也是500px,那么在500px的屏幕上呢?他会标注250px,一般公司里面出视觉稿,视觉稿宽度值是固定的:640p或者720p,因此最终值确实和视觉稿所用宽度有关,另外也可以知道B/S实际上是这个元素的宽度与屏幕宽度的比例。

除去B和S,A(开发的手机宽度像素值)和D(屏幕密度)又怎么解释呢?根据前面的结论,我们修改一下公式: B/S=XD/A 。前面说了B/S的含义,XD则是元素实际显示的物理尺寸,A是手机实际的物理宽度,那么这个比展现的就是我们之前的目标。

问题来了,AB/DS到底怎么算?实际上B和S很容易得到,B是标注,S一般为640或者720,A和D却一直在变化,BUT!!! 它们的比却相对固定——目前主流手机(三星、小米、中兴等)这两个值基本是(720,2)或者(1080,3)的配比,除一下很容易得到360这个结果(Nexus 5也是这个值),部分手机在此上下浮动(比如魅族,383),在此基础上,如果UED出图的标准宽度是720px,很容易得到 X = 0.5B 这个结果,即将UED的标注除以2就可以了,如果是640px,则需要乘以1.125才能得到正确的值。

备注: 很多手机的ppi实际上不是160的整数倍,也不是x.5倍,在官网上,hdpi、mdpi、xhdpi等的定义是对应一个范围的,手机系统在这里会做一个换算,使得从手机上获取的屏幕密度值基本上是一个整数或者x.5值,比如2.0,3.0,1.5。比如我的Nexus 5手机,屏幕密度是3.0,实际的ppi是445,并不是160 * 3.0 = 480ppi。

##最后 720p的图标注除以2,640p的则还要乘以1.125,公司UED一直有这个"奇怪"的规定,但是在某些情况下,他们并不适用。以上分析可以看出,这个结论是基于一些事实的,当A/D不是360并且浮动比较大的时候,这个规则就不再成立。