(Yunqing, Wang @ BroadVision)总结的。我分享一下。

----------------

在这个日新月异的年代,安卓系统和安卓手机都在快速得发展和更新,于是出现了各种版本的安卓系统和各种配置(屏幕尺寸、屏幕密度、分辨率等)的安卓手机。当一个应用提供一个图片资源时,如果采取一些措施,从视觉角度该图片就会在不同的手机上呈现相同的效果。那么,都有哪些措施,这些措施是如何工作的呢?接下来是笔者对此问题的研究心得,希望对你有所帮助。

首先阐释一些术语和概念

Ø  屏幕尺寸(screen size):实际的物理尺寸,屏幕的对角线测量。为了方便,Android把所有的屏幕尺寸分为了4个广义的大小:小、正常、大、更大。

Ø  屏幕密度(screen density):屏幕占据的物理区域所含像素的个数,通常被称为dpi(dots per inch)即每英寸的像素点数。

Ø  分辨率(resolution):屏幕上物理像素的点数。例如,有一个240px*400px的屏幕,可以理解为在这个屏幕上横着有400条线,每条线上有240个像素点。

Ø  像素(px):屏幕上的点。

Ø  dip(dp):Density-independent pixel--->与密度无关的像素(下面将详细讲解)

dpi如何计算

 

只要我们知道屏幕分辨率、屏幕尺寸(对角线长度),就可以算出相应的屏幕密度,从而根据其范围得出属于那种屏幕密度。

我们可以根据长或者根据宽来计算出dpi,计算公式为:

DPI

或者以下方法

以宽为例:

1.比如分辨率为320 × 480,则长宽比为1:1.5

2.比如屏幕尺寸为3.6英寸,则根据勾股定理:

宽的平方 + 长(或叫做 高)的平方 = 对角线的平方。

设宽为 x,则高为1.5x, 对角线长度为 3.6英寸。

则 x^2 + (1.5x)^2 = (3.6 inch)^2

则 3.25 x^2 = (3.6 inch)^2

则 x^2 = 3.6^2 / 3.25

则 x =  1.9969 inch

得出,

宽 = 1.9969英寸

3.宽为320px,分布在1.9969英寸上,因此密度为320/ 1.9969 = 160.2467

4.因此此密度约为mdpi的密度

决定屏幕清晰度的是什么?

 

常见的位图的最小组成单位是像素,那么单位物理长度内的像素数越多,图像就会越清晰。很多人都说跟屏幕大小没直接关系,因为还有分辨率,可是如果一个屏幕的分辨率很大,但屏幕也非常的大,那么单位长度内的像素数不一定很大。所以决定屏幕清晰度的是单位物理长度的像素数,也就是上面所说的屏幕密度。

Android设备屏幕尺寸分布

 

首先看一下各种屏幕的尺寸和屏幕密度划分,下图是各种屏幕尺寸对应的范围:

图1:

从上图可以看出,对应normal尺寸的屏幕范围集中在常见的3到5寸屏之间,large尺寸对应的就主要是5到7寸的nottpad之类的设备,例如三星的Note和Nexus7平板等,再网上走就是平板电脑了。接下来是屏幕密度(dpi),需要说明的是,平时所说的屏幕分辨率其实不能作为屏幕适配的依据,应该依据屏幕密度和屏幕尺寸来换算,屏幕密度是指每英寸屏幕内容纳的像素数,屏幕密度从ldpi到xhdpi分别对应为120dpi、160dpi、240dpi、320dpi,屏幕密度越高、分辨率越高、屏幕尺寸越小就产生了视网膜屏幕。

dip单位详解

Android规定一个dip的大小相当于160dpi屏幕上的一个像素,它是系统为“中等的”密度屏设定的基准密度,在不同dpi屏幕上dp对应的像素数是不同的。需要时,基于当前屏的实际密度,系统会透明地放缩dip单。dip单位根据公式像素值 = [dip*(dpi/160)](px)(其中px是单位)转化为屏幕像素。根据此公式可以计算出一个dip分别在120dpi、160dpi、240dpi、320dpi屏幕中对应的像素数分别为0.75、1、1.5、2.0,比例为3:4:6:8,如下图。因此,在不同屏幕密度上,以mdpi作为基准,对位图进行3:4:6:8比例的放缩会达到适配的效果。

图2:

dip与一般的px不太一样,它是独立于屏幕密度的。什么是独立于密度?

先来说下一般的px,如果将一个相同长宽像素的图片放在不同屏幕密度大小的屏幕中,那么,在低密度屏幕中图片会显示的很大,在高密度屏幕中则会显示的很小;但是,如果使用dip为单位的图片显示的效果则是,屏幕密度越大的手机,图片显示的像素也相应增大,这样在屏幕密度大的手机和屏幕密度小的手机上,图片看上去大小基本相同。有了上文对dip的讲解,是否对这个现象有所理解呢?

举个例子来说一下:

现在有三个物理长宽分别为3寸、4寸,屏幕密度分别为120dpi、160dpi、240dpi的手机,则三个屏幕的分辨率分别为360px*480px、480px*640px、

将三个手机屏幕的宽分为三等份,则根据dpi的定义,三个屏幕中每等份分别容纳120px、160px、240px。现在假设有一个控件imageview 它的长宽分别为160px、160px,还有一个160px*160px的图片资源,当程序运行时,该图片在三个屏幕上会呈现以下效果:

                       在这三个屏幕上,图片占据的都是160px*160px的大小范围

如果将imageview的长宽分别改为160dip、160dip,图片将在三个屏幕上呈现以下效果:

上文提到在这三种屏幕密度下一个dip分别对应0.75px、1px、1.5px,所以在三种屏幕上该图片占据120px、160px、240px,各自占屏幕的三分之一,所以看起来是一样大的。

由上文可总结出Android在适配不同屏幕密度时,可以用dip作为控件的单位,视情况放缩dip单位。

当应用没有指出图片对应的控件的大小,Android是如何让图片适配不同屏幕的呢?

在Android2.1之前,开发应用时只有一个放图片资源的drawable文件夹,这样程序在不同屏幕密度的手机上运行时,系统只会从drawable这个文件夹下调图片资源,并且系统会默认认为这个文件夹下的所有资源是为mdpi屏幕提供的,所以在hdpi屏幕上系统会按比例将drawable下的图片扩大为原来的1.5倍,在ldpi屏幕上系统会按比例将drawable下的图片缩小为原来的0.75倍。这样会大大降低页面效果。

在Android2.1以及之后,出现了drawable-ldpi、drawable-mdpi、drawable-hdpi、drawable-xhdpi、drawable-xxhdpi。在这些文件下提供的图片大小最好是3:4:6:8:12。程序在不同的屏幕密度下运行时,会首先去符合当前屏幕密度的文件夹下找对应的资源,如果没有,系统会以最省力为前提去别的文件夹下找对应的资源并对其进行相应的缩放,如果还没有,就回去默认的drawable文件夹下找,然后按照2.1之前的规则缩放。如果还没有找到,应用就会报错或者直接crash掉了。

举个例子:现在有一个ldpi的手机屏幕,有一个应用在其上运行(假如只有ldpi、mdpi、hdpi还有drawable四个存放图片的文件夹),并需要调用一个图片a.png(在下文中用a来代替a.png)。Android系统会经历以下流程:

注:

将hdpi中的图片大小缩小为原来的一半相比将mdpi中的图片大小缩小为原来的3/4,计算机要省力,只需进行简单地右移一位操作。所以系统在ldpi下找不到a的时候会首先去hdpi下去找。当存在xhdpi、xxhdpi时,系统会按相同的规则去调用资源。

Drawable-ldpi 3、Drawable-mdpi  4、Drawable-hdpi  6中的3、4、6指的是同一个图片在三个文件夹下的大小之比。

总结

Android开发者在做图片适配时需要注意一下两点

1、盛放图片的控件要用dip单位来定义其长宽。

2、  最好在ldpi、mdpi、hdpi、xhdpi、xxhdpi文件夹下提供大小比例为3:4:6:8:12的图片。当然如果有质量好的.9.png图片的话,提供一个也可以。

本文参考官方文档:

http://developer.android.com/guide/practices/screens_support.html

Android是如何在不同屏幕上适配图片的 -- 或控件大小相关推荐

  1. Android之RemoteViews篇上————通知栏和桌面小控件

    Android之RemoteViews篇上----通知栏和桌面小控件 一.目录 文章目录 Android之RemoteViews篇上----通知栏和桌面小控件 一.目录 二.RemoteViews的概 ...

  2. 屏幕上锁定图片_如何在Windows 8锁定屏幕上自定义时间

    屏幕上锁定图片 If you are running Windows 8, hit the Windows key and L at the same time. What do you see? I ...

  3. Visual C++——获取屏幕大小、窗口大小、对话框大小和位置、控件大小和位置

    解决方案 获取屏幕大小 //下边两个函数获取的是显示屏幕的大小,但不包括任务栏等区域int cx = GetSystemMetrics(SM_CXFULLSCREEN); int cy = GetSy ...

  4. selenium Element is not clickable because another element obscures it — 点击被页面上其他元素遮住的控件,亲试有效!!!

    点击被页面上其他元素遮住的控件 使用WebDriver点击界面上Button元素时,如果当前Button元素被界面上其他元素遮住了, 或没出现在界面中(比如Button在页面底部,但是屏幕只能显示页面 ...

  5. COM组件开发实践(七)---多线程ActiveX控件和自动调整ActiveX控件大小(上)

    声明:本文代码基于CodeProject的文章<A Complete ActiveX Web Control Tutorial>修改而来,因此同样遵循Code Project Open L ...

  6. android 动态设置padding,Android动态设置控件大小以及设定margin以及padding值

    http://www.aichengxu.com/Java/73893.htm Android动态设置控件大小以及设定margin以及padding值,有需要的朋友可以参考下. 一.概述 在andro ...

  7. Android 软键盘弹出时把布局顶上去,控件乱套解决方法

    Android 软键盘弹出时把布局顶上去,控件乱套解决方法 参考文章: (1)Android 软键盘弹出时把布局顶上去,控件乱套解决方法 (2)https://www.cnblogs.com/zhuj ...

  8. WPF 获取鼠标屏幕位置、窗口位置、控件位置

    原文:WPF 获取鼠标屏幕位置.窗口位置.控件位置 public struct POINT{public int X;public int Y;public POINT(int x, int y){t ...

  9. android 图片轮播组件,Android客户端实现图片轮播控件

    本文和大家一起写一个Android图片轮播控件,供大家参考,具体内容如下 1. 轮播控件的组成部分 我们以知乎日报Android客户端的轮播控件为例,分析一下轮播控件的主要组成: 首先我们要有用来显示 ...

  10. android banner加载布局,Android知识点之图片轮播控件Banner

    Rate this post 在我们来发Android项目时,经常有图片或者广告的轮播功能的需求,下面将介绍一款Android开发时使用的开源图片轮播控件Banner,同时按序讲解如何使用配置这款控件 ...

最新文章

  1. 智能车竞赛技术报告 | 智能车视觉 - 首都师范大学 - 首师智能视觉
  2. SDM管理路由器要进行的相应配置
  3. Git内部原理之深入解析维护与数据恢复
  4. 类与类集合的基本使用
  5. solr4.6本地数据提交异常
  6. bash的一些小技巧
  7. 安装kinnect v1驱动
  8. SparkStreaming与kafka的结合
  9. Java Map 接口
  10. 六、Oracle学习笔记:字符串函数
  11. PaaS适用于哪些场景?让案例说话
  12. 【控制】动力学建模举例 --> 牛顿-欧拉法
  13. [转自他人]一款好用的软件安装管理器
  14. win7下面用超级终端不能输入命令原因
  15. 抢火车票,出行必备程序(12306bypass)--可以抛掉同程什么的抢票软件了
  16. 龙芯2F装debian5
  17. 含耦合电感元件的电路分析
  18. 嵌入式培训经验分享——初识
  19. 如何使用Python还原村上春树笔下经典的那句“我爱你像爱春天的小熊”
  20. vue渲染大量数据优化_vue大数据表格卡顿问题的完美解决方案

热门文章

  1. 你不知道的JavaScript APIs
  2. [GDC 2015] Scroll Back - 2D 卷轴游戏的摄影机理论与实务
  3. mysql取倍数的数据_MySQL 基本命令
  4. 我的游戏开发收藏夹 (不定期更新)
  5. mysql查询多选项商品查询_MYSQL中的多类型查询及高级查询操作
  6. python修改植物大战僵尸阳光值
  7. 基于pyagme用python做接小球游戏
  8. Qt开发总结(19)——Qt Charts
  9. 汇编语言学习篇2——MASM的环境搭建(win10与Ubuntu1604下的配置)【有问题,待更正】
  10. np.digitize 用法详解