那些恶心人的Screen基本概念
Screen的这些基本概念中,最重要的就是dip的理解,而理解dip就是理解android适配不同设备的关键。
Screen Size
实际物理尺寸。就是我们常说的3.5英寸屏幕,4.7英寸屏幕等等,这个长度说的是对角线的长度。在android中屏幕物理尺寸划分为这么几类:small,normal,large,extra large。下面是对尺寸以及密度的一个粗略分类。该图可能会由于实际设备尺寸和屏幕密度的不断增加而更新,最新的请到官网查看。

图1
Resolution
“屏幕”分辨率,即屏幕上的像素总数。常用的表现形式如:1280x720, 1920x1080等。
Screen density
屏幕密度,与dpi表达的同一个意思,两种不同的描述方式。官网如是说:
Screen density
The quantity of pixels within a physical area of the screen; usually referred to as dpi (dots per inch). For example, a "low" density screen has fewer pixels within a given physical area, compared to a "normal" or "high" density screen.
public floatdensityThe logical density of the display.
public intdensityDpiThe screen density expressed as dots-per-inch.
但其实我的理解他就是一个缩放系数,具体原因在后面解释。按照屏幕密度所有的手机可被划分为以下几类:ldpi (low,低密度), mdpi (medium,标准密度), hdpi (high,高密度), and xhdpi (extra high,超大密度)。
DPI(dot per inch)
每英寸像素数。与density描述的都是屏幕的密度。但请注意这个翻译,实际上应该译为每英寸点数。为说明原因,不得不引入另一个概念:PPI(Pixel per inch),每英寸像素数。实际PPI用于电脑显示领域,DPI用于打印或印刷领域,但从很久之前两个概念就已经开始混用:
“点”有时用来表示像素,特别是计算机市场,由于计算机显示器如LCD或CRT是由一个个极小的点来描绘图像的,LCD显示器在标准屏幕分辨率下,对于一个像素可认为是由显示器的一个“点”来显示,因此ppi有时所写为DPI(dots per inch,每英寸点数)——维基百科:像素
到android这里,干脆就用dpi取代ppi代表像素密度。
DPI计算方法
像素密度=屏幕总像素数/屏幕大小。通常我们知道屏幕的尺寸是诸如3.5英寸,5.0英寸等,这是对角线长度,我们可以先获取对角线上的总像素数,再除以对角线长即可。
拿Mi2s举例说明:4.3英寸,1280x720。对角线上像素值根据勾股定理可得√(1280^2+720^2)≈1468.6,接着1468.6/4.3≈341.5
然而,从代码测试的结果看起来是有偏差的:
Density:2.0
DensityDpi:320
Resolution:1280x720
xDpi:345.0566 // x方向上(宽)每英寸像素数
yDpi:342.23157 // y方向上(高)每英寸像素数
可以看出,xDpi≈yDpi≈341,与我们的计算结果相近。但DensityDpi是320,为什么呢?在Screen Density中已经说过,android将所有屏幕的实际密度归类,处在某个区间内的密度是个定值,参考下表:
| 密度分类 | DPI值(像素/英寸) | Density值 |
| ldpi | 120 | 0.75 |
| mdpi | 160 | 1 |
| hdpi | 240 | 1.5 |
| xhdpi | 320 | 2 |
| xxhdpi | 480 | 3 |
表1
根据图1种的分类,Mi2s的真实dpi为341,341>300,所以Mi2s属于xhdpi,再结合表1,得出DensityDpi=320。
从上面的数据也可以看出Density和DensityDpi值不同,但规律是显而易见的。在android中,mdpi是标准值,android将其density定为1,以此为准得出Density与DensityDpi的关系是:dpi=density*160。
我的疑问是,既然dpi可以代表屏幕密度,还要density干什么?想要搞清楚该死的density,必须要结合dp,往下看。
Density-independent pixel (dip,或dp)
独立像素,虚拟单位,又称设备无关像素。1dp的长度相当于一个160dpi的屏幕上一个物理像素的长度。而160dpi的屏幕则是被android定义为基准的屏幕(mdpi)。在app运行的时候,android会将dp转为实际像素进行布局。转换的公式为:px = dp * (dpi / 160)。
为什么要dip
设想app将一张图以像素为单位进行布局,该图为400px的正方形图,当app运行在1920x1080上时看起来比较小,运行在960x640上时显得非常的大,而我们想要看到的效果是app运行在两个手机上时这张图看起来是大小相近的效果。
看下面这张图是以px为单位进行布局的效果:

图2
下面这张图是使用dp布局的效果:

图3
想要达到这样的效果,就需要在高密度手机上对其进行放大操作,低密度手机上对其进行缩小操作。但是我们无法预期自己的app会安装在什么密度,什么尺寸的手机上,即使知道也不可能为每个手机准备一套图,因此希望android能智能一些,我设置一个大概的尺寸,android能自动适配不同手机。于是就有了独立像素这个单位。见名之意,开发人员只需要用dp或者直接使用wrap_content,剩下的交给android,系统会为你的布局和图片做缩放。
dp怎么来的
那么,android是如何创造出这个独立像素的?
首先,我们的思路是从原来用px进行布局,改为用dp布局,由于最终dp还是要转化为px,引入一个系数λ,则有:px=dp*λ,λ就是我们的缩放系数;
其次,我最终目标是让所有手机上看到的图大小相同,那么到底多大,是不是要有个标准,我就选一个定做标准,让其他不同密度的手机显示的跟这个标准一样大。那么我把这个标准就定为160像素/英寸吧,取个名字叫mdpi,接着把其他密度的手机进行分类:ldpi(120像素/英寸),hdpi(240像素/英寸),xhdpi(320像素/英寸);
再次,归类都归好了,下面就开始缩放吧:
当app运行在标准手机上(mdpi),图片应该不缩放,因为它是标准,即λ=1,此时px=dp;
当app运行在ldpi手机上时,由于密度小于标准,图像的长更长,宽更宽,为了保持与标准相同的长宽,在ldpi上长要缩小原来的120/160=0.75,宽亦如此,即λ=0.75,此时px=0.75*dp;
当app运行在hdpi上时,λ=1.5,px=1.5*dp;
以此类推。。。
由上面的推导,其实λ=dpi/160=density,可见density就是λ。
结论
1. 从官网的概念得知density与dpi都是描述屏幕密度的,似乎是相同的概念,但何必用两个同名概念来描述让人混淆呢?我个人觉得何不把他们从命名上做个区分,density就是个缩放系数,dpi才是对密度的准确描述。因此我只用dpi来表示屏幕密度,或像素密度,而density其实就是缩放系数,或密度系数;
2. 即使在某一个密度分组区间内(比如xhdpi)不同的密度的手机所展示的同样大小的图片,仔细看也不会完全相同,毕竟他们的密度不同。因此android只是尽最大可能简化适配的工作,分组并不能百分百解决适配的问题。
SP
专用于android中的字体大小。sp产生的初衷与dp是相同的,只是它应用于字体大小。
那些恶心人的Screen基本概念的更多相关文章
- Android核心分析 之二方法论探讨之概念空间篇
方法论探讨之概念空间篇 我们潜意识就不想用计算机的方式来思考问题,我们有自己的思维描述方式,越是接近我们思维描述方式,我们越容易接受和使用.各种计算机语言,建模工具,不外乎就是建立一个更接近人的思维方 ...
- oracle实例名,数据库名,服务名等概念差别与联系
数据库名.实例名.数据库域名.全局数据库名.服务名 这是几个令非常多刚開始学习的人easy混淆的概念.相信非常多刚開始学习的人都与我一样被标题上这些个概念搞得一头雾水.我们如今就来把它们弄个明确. 一 ...
- 《人月神话》读书笔记(2)-week3
为了确保团队中的每个人都能保持系统概念上的完整性,关于项目的书面规格说明是必不可少的.手册要描绘用户可见的一切,但不应支配实现的过程.光有规格说明也是不够的,会议也是必要的.书中提到的周例会会迅捷地给 ...
- 如何卸载烦人的2007组件,windows提供的解决方案
如何卸载烦人的2007组件:很恶心人各种软件已经手动删除卸载都无法用,不是cd/dvd找不到就是什么msi文件找不到:对于这种恶心的问题,windows提供了如下解决方案:我使用fixit轻松卸载,很 ...
- css 选择器三
2.4.10 浮动 浮动是css里面布局最多的一个属性,也是很重要的一个属性. float:表示浮动的意思.它有四个值. none: 表示不浮动,默认 left: 表示左浮动 right:表示右浮动 ...
- Hibernate级联操作 注解
EJB3 支持的操作类型 /** * Cascade types (can override default EJB3 cascades */ public enum CascadeType { AL ...
- 关于Store Apps
因为时代在变迁,Store Apps这个概念很容易引起混淆 在过去,windows phone 8.0时代 windows store apps指的是windows metro style 的应用, ...
- 我的美国(北美)计算机CS实习面试经验分享
过去的一年多里,参加了一些面试,虽然面过的公司不多,但都从头一直走到尾.毕竟自己也是花了大量的时间和精力在这一场场的面试里.所以,就絮叨下自己的一些经验,希望能给在美国找实习找工作的同学们提供一点点帮 ...
- 再谈Hibernate级联删除——JPA下的Hibernate实现一对多级联删除CascadeType.DELETE_ORPHAN
声明: 1.本文系原创,非抄袭或转载过来的. 2.本文论点都亲手做过实验论证. 3.本文所讲的Hibernate配置都基于注解的方式,hbm语法未提供. 非常多人对持久层概念搞不清JPA.Hibern ...
随机推荐
- window安装Scrapy———解决报错问题
系统是WIN10 64位Python是3.5.2今天安装pip install Scrapy 来安装发现报错Microsoft Visual C++ 14.0 is required 检查发现电脑中 ...
- Jump Game leetcode java
题目: Given an array of non-negative integers, you are initially positioned at the first index of the ...
- 分享七个绚丽夺目的JQuery导航(还有苹果、猪八戒等),有图有真相
今天来一起看看几个个人觉得比较好的导航.有好几个导航是仿的,比如仿苹果.仿猪八戒等等,但仿得还都不错.也有不少是基于jQuery的.特别是像我这样的懒人,就可以在这些基础上修修改改作为自己网站项目的导 ...
- 几行简单代码实现DIV层上显示Tooltip效果
最近在做一个项目,要在鼠标移到层上后显示出tip提示,网上找了半天,都很麻烦,就自己修改了一个,记录在下面 测试在IE 7.8.9及 chrome 上没问题. <HTML> <HEA ...
- NYOJ-712 探寻宝藏(第六届河南省程序设计大赛)
探 寻 宝 藏 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫 ...
- scala 学习笔记七 基于类型的模式匹配
1.介绍 Scala 提供了强大的模式匹配机制,应用也非常广泛. 一个模式匹配包含了一系列备选项,每个都开始于关键字 case.每个备选项都包含了一个模式及一到多个表达式.箭头符号 => 隔开了 ...
- python 分词计算文档TF-IDF值并排序
文章来自于我的个人博客:python 分词计算文档TF-IDF值并排序 该程序实现的功能是:首先读取一些文档,然后通过jieba来分词,将分词存入文件,然后通过sklearn计算每一个分词文档中的tf ...
- 2013级C++第14周(春)项目——多态性、虚函数和抽象类
课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 第一部分 阅读程序1.阅读.改动和执行关于交通 ...
- [NPM] Execute npx commands with $npm_ Environment Variables
We will incorporate npm specific environment variables when executing various npx commands. In our e ...
- Linux History安全问题【保存记录防止删除】+完善Linux/UNIX审计 将每个shell命令记入日志
2011-09-27 22:11:51| 分类: rhel5_033|举报|字号 订阅 Linux利用PROMPT_COMMAND实现审计功能 这个系统审计,记录什么用户,在什么时间,做 ...