原始尺寸场景



相信大家对上面也有所有耳闻另外就是如何计算屏幕的密度一般都是按照勾股定理例如中等屏幕密度 480^2+800^2开根号 然后除以当前屏幕尺寸3.5-4.2之间尺寸。

对于刚出来的那些Android职场的小鸟,适配的确是一件很头痛的事情,现在相信大家都知道主流的屏幕是xhdpi(超高屏幕702*1280)和xxhpi(高清屏幕1080*1920)但是有些公司为了节约成本只用iphone1x然后android根据px进行换算一般都是px转dp是px

除以2dp=px/2

Px (Pixel像素)

也称为图像元素,是作为图像构成的基本单元,单个像素的大小并不固定,跟随屏幕大小和像素数量的关系变化(屏幕越大,像素越低,单个像素越大,反之亦然)。所以在使用像素作为设计单位时,在不同的设备上可能会有缩放或拉伸的情况。

Resolution(分辨率)

是指屏幕的垂直和水平方向的像素数量,如果分辨率是 1920*1080 ,那就是垂直方向有 1920 个像素,水平方向有 1080 个像素。

Dpi(像素密度)

是指屏幕上每英寸(1英寸 = 2.54 厘米)距离中有多少个像素点。如果屏幕为 320*240,屏幕长 2 英寸宽 1.5 英寸,Dpi = 320 / 2 = 240 / 1.5 = 160。

Density(密度)

这个是指屏幕上每平方英寸(2.54 ^ 2 平方厘米)中含有的像素点数量。

Dip / dp (设备独立像素)

也可以叫做dp,长度单位,同一个单位在不同的设备上有不同的显示效果,具体效果根据设备的密度有关,详细的公式请看下面 。

计算规则

我们以一个 4.95 英寸 1920 * 1080 的 nexus5 手机设备为例:

Dpi :

计算直角边像素数量: 1920^2+1080^2=2202^2(勾股定理)。

计算 DPI:2202 / 4.95 = 445。

得到这个设备的 DPI 为 445 (每英寸的距离中有 445 个像素)。

Density

上面得到每英寸中有 440 像素,那么 density 为每平方英寸中的像素数量,应该为: 445^2=198025。

Dip

先明白一个概念,所有显示到屏幕上的图像都是以 px 为单位。

Dip 是我们开发中使用的长度单位,最后他也需要转换成 px。

计算这个设备上 1dip 等于多少 px:

px = dip x dpi /160

px = 1 x 445 / 160 = 2.78

通过上面的计算可以看出在此设备上 1dip = 2.78px,那么这是一个真实的故事吗? nonono,其中的关键值 dpi 并不是我们算出来的 445 ,请往下看。

Android 系统定义的 Dpi

上面计算的 445Dpi 是在 4.95 英寸下的 1920*1080 手机,那如果是 4.75 分辨率下的呢? 4.55 分辨率下的呢?。。。。可见是很麻烦的,同一个分辨率在不同的屏幕尺寸上 Dpi 也不相同。为了解决这个问题, Android 中内置了几个默认的 Dpi ,在特定的分辨率下自动调用,也可以手动在配置文件中修改。

ldpi mdpi hdpi xhdpi xxhdpi

分辨率 240×320 320×480 480×800 720×1280 1080×1920

系统dpi 120 160 240 320 480

基准比例 0.75 1 1.5 2 3

这是内置的 Dpi ,啥意思? 在 1920*1080 分辨率的手机上 默认就使用 480 的 dpi ,不管的你的尺寸是多大都是这样,除非厂家手动修改了配置文件,这个我们后面再说。

Pt

point,是一个标准的长度单位,1pt=1/72英寸,用于印刷业,非常简单易用。

我们亲自尝试一下:

<TextView
  android:id="@+id/tv"
  android:layout_width="200dp"
  android:layout_height="100dp"
  android:text="Hello World!" />

这是一个 textview,高为 200dp 宽为 100dp 。按照我们之前的公式手动计算:

height = 100 x 445 / 160 = 278.5px
width  = 200 x 445 / 160 = 556.25px

我们用下列代码获取到控件的实际像素看看是否相同:

layout = (RelativeLayout)findViewById(R.id.la);
//要在控件绘制完成后才能获取到相关信息,所以这里要监听绘制状态
layout.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()     {
  public boolean onPreDraw() {
    Log.d("hehehe", textView.getHeight() + "/" + textView.getWidth());
    return true;
  }
});

输出的结果为:300/600

内部计算过程为:

height = 100 x 480 / 160 = 300px
width  = 200 x 480 / 160 = 600px

其中的 160 是基准值不会变的, 100 和200 是我们设置的 dp ,那么这 480 是从何而来的?说好的 445 呢?

找到我们手机中的 /system/build.prop 文件,其中有一行是ro.sf.lcd_density=480定了这个机型使用的dpi是多少,还有一种情况是没有这一行(我在模拟器中发现过),那么应该是根据表格中的分辨率来自动设置。

我更改这行为:

ro.sf.lcd_density=320

再次运行上面的测试代码,输出结果为:200/400

内部计算过程为:

height = 100 x 320 / 160 = 200px
width  = 200 x 320 / 160 = 400px

说到底,因为有dpi这个动态的系数,我们在使用dp的时候才能兼容不同分辨率的设备。

到这里,应该都明白了 dpi 的由来,以及系统 dpi 跟物理 dpi 并不一定相同。在系统中使用的全部都是系统 dpi,没有使用物理 dpi,也获取不到物理 dpi。物理 dpi 主要用于厂家对于手机的参数描述(也可以看做 ppi )!

然后。。表格中还有一个东西叫做基准比例,这个其实就是计算 dp -> px 中重要的系数,以 160 为基准,其他的除以 160 得到比例,我们这样看:

height = 100 x 480 / 160 = 300px
width  = 200 x 480 / 160 = 600px

其中的480/160其实就是在求基准比例,这里得到3。如果在熟悉上表的情况下看到机型的分辨率,在设置dp的时候可以直接心算出相对应的px,心算过程如下:

分辨率:1080×1920 -> 系统 DPI:480 -> 基准比例:480 / 160 = 3 -> 对应px:100 x 3 = 300

分辨率:720×1280 -> 系统 DPI:320 -> 基准比例:320 / 160 = 2 -> 对应px:100 x 2 = 200

分辨率:480×800 -> 系统 DPI:240 -> 基准比例:240 / 160 = 1.5 -> 对应px:100 x 1.5 = 150

分辨率:320×480 -> 系统 DPI:160 -> 基准比例:160 / 160 = 1 -> 对应px:100 x 1 = 100

分辨率:240×320 -> 系统 DPI:120 -> 基准比例:120 / 160 = 0.75 -> 对应px:100 x 0.75 = 75

……………….

总结:

  1. dpi(每英寸像素数)是有预设值的!120-160-240-320-480。对应不同的分辨率。

  2. 基准比例 = dpi(每英寸像素数) / 160

  3. px = dp x 基准比例

从代码中获取相关数值

我们主要使用的类是:DisplayMetrics

以下为官方api说明

A structure describing general information about a display, such as its size, density, and font scaling.

To access the DisplayMetrics members, initialize an object like this:

DisplayMetrics metrics = newDisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(metrics);

这是一个获取屏幕信息的类,比如大小,密度等。以及初始化的方法。

实际运用如下:

dm.heightPixels + 32 * dm.ydpi / 160;

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
//通常我们在使用DisplayMetrics时,都是直接获取内部变量来使用。所以下面直接列出各个内部变量。

dm.ydpi;     //得到物理屏幕上 Y 轴方向每英寸的像素
dm.xdpi;     //得到物理屏幕上 X 轴方向每英寸的像素
             //ps:  其实这两个大多数情况下都是相同的
             //你能想象上面像素密度大很清晰 下面密度小跟马赛克一样吗 233333

dm.density;           //获取当前设备的基准比例
dm.densityDpi;        //获取系统dpi,随着 build.prop 文件中的代码而改变。

dm.widthPixels;       //获取屏幕宽度的像素数量

//获取屏幕高度的像素数量!
//注意 - 因为这里会自动减去32dp的像素数量,根据分辨率不同的设备,减去的像素数量也不同,但是可以根据公式推算完整(px = dp x 基准比例)。
/*为啥不用dm.densityDpi / 160 得到基准比例?
  因为那个会随着build.prop文件代码变更而更改,算出来的不一定准确*/
dm.heightPixels + 32 * dm.ydpi / 160;

参考链接:

最新Android&Ios设计尺寸规范

一款App从设计稿到切图

Android界面设计视觉规范

标你妹啊自动标注

写在最后

1、希望大家有意见的可以给出一些解决方案,目前UI给我的是720的尺但是我手机屏幕是1080*1920屏幕大小5.5寸

2、我用标你妹啊iphone1x 适合720的宽度 但是字体好像不对 !

3、我自己正在整理一些方案 目前还在测试中,希望大家踊跃留言真心感谢!

4、之前我按照ui给我720的除以1.5/1.8/2.0/2.5都试了并没什么卵用!

[置顶] Android 适配真要命?的更多相关文章

  1. [置顶] Android开发笔记(成长轨迹)

    分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...

  2. [置顶] Android AlarmManager实现不间断轮询服务

    在消息的获取上是选择轮询还是推送得根据实际的业务需要来技术选型,例如对消息实时性比较高的需求,比如微博新通知或新闻等那就最好是用推送了.但如果只是一般的消息检测比如更新检查,可能是半个小时或一个小时一 ...

  3. [置顶] Android布局管理器 - 详细解析布局实现

    布局管理器都是以ViewGroup为基类派生出来的; 使用布局管理器可以适配不同手机屏幕的分辨率,尺寸大小; 布局管理器之间的继承关系 : 在上面的UML图中可以看出, 绝对布局 帧布局 网格布局 相 ...

  4. [置顶] [Android源码分析]inquiry result引起的上层变化分析

    在上一篇文章中,我们详细分析了android是如何解析蓝牙反馈上来的搜索到的设备信息,本文将会继续分析这些信息到了上层之后是如何处理. 8.inquiry result引起的上层变化 我们知道inqu ...

  5. [置顶] Android四大组件之BroadcastReceiver

    Android四大组件之BroadcastReceiver Broadcast Receiver 广播接收器,是一种负责接收广播消息并对消息做出响应的组件,和Service一样并不提供与用户交互的UI ...

  6. [置顶] Android开发实战记录(三)---HelloWorld

    1.新建Android项目,选择Android Project,然后Next 2.填写项目名称HelloWorld然后next,这里注意下,Java开发的命名规范 3.选择Android SDK版本, ...

  7. [置顶] Android图片异步加载之Android-Universal-Image-Loader

    将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...

  8. [置顶] Android 状态栏那些小坑?

    背景:因为之前老板上次问我我们的app能不能自定义上面的状态栏我说可以啊!当时没管,今天试了下果然很多坑,之前github上也有很多大佬写了一个开源库有兴趣的可以点进去看下支持DrawLayout沉侵 ...

  9. [置顶] Android AOP 实践笔记

    本文同步自wing的地方酒馆 最近博客更新越来越慢了,有两方面原因: 1.没啥好写的. 2.应该沉下心好好沉淀自己,积累一些东西,博客写的太频繁有"刷博客"之嫌,还容易浮躁. 浮躁 ...

随机推荐

  1. PAT 天梯赛 L1-045. 宇宙无敌大招呼 【水】

    题目链接 https://www.patest.cn/contests/gplt/L1-045 AC代码 #include <iostream> #include <cstdio&g ...

  2. seven habits of highly effective people 高效能人士的七个习惯

    习惯的模型 : dependent 依赖  -- independent 独立自主 --interdependent  互相依赖 1: be  proactive 主动积极 what you can ...

  3. linux(6/17)--文件打包上传和下载

    tar命令 命令功能 用来压缩和解压文件 命令格式 tar[必要参数][选择参数][文件] tar打包工具 -f ##指定生成包的名字,建议 -f单独写成一个参数 --delete filename ...

  4. CSS3:布局display属性的flex(弹性布局)

    CSS3:布局display属性的flex(弹性布局) 一.简介 Flex是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性.设为Flex布局以后, ...

  5. jQuery动画二级下拉菜单

    在线演示 本地下载

  6. 会话控制Cookie的应用

    Cookie是一种由服务器发送给客户端的片段信息,存储在客户端浏览器的内存或者硬盘上,在客户端对服务器的请求中发回它.PHP透明地支持HTTP Cookie.可以利用他在远程浏览器端存储数据并以此来跟 ...

  7. maven项目在eclipse的library中没有Maven Dependencies

    今天使用maven创建了一个多模块的项目,在分别创建完父项目和各个子模块后,编译父项目的时候,父项目工程目录上出现了一堆红叉叉,点进去一看,是找不到依赖的类,但是pom文件中相应jar的depende ...

  8. Hibernate : Query.list()、Query.iterator()的区别

    Query上有list()与iterator()方法,两者的差别在于list()方法在读取数据时,并不会利用到快取,而是直接再向数据库查询,而iterator()则将读取到的数据写到快取,并于读取时再 ...

  9. [BZOJ1018]堵塞的交通traffic

    Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一 ...

  10. 洛谷P4311 士兵占领

    题目描述 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放置了Li个士兵 ...