Android 关于"尺寸"的那些事(dp,dip,sp,pt,px...)

Android 关于"尺寸"的那些事(dp,dip,sp,pt,px...),第1张

屏幕大小:屏幕大小是手机对角线的物理尺寸,以英寸inch为单位。比如我的Mix 2手机屏幕大小为599 inches,意味着我的屏幕对角线长度为599inches = 599 254 = 152146cm

分辨率:屏幕的像素点数,一般表示为ab。例如某手机分辨率为21601080,意味着手机屏幕的竖直方向(长)有2160个像素点,水平方向(宽)有1080个像素点。

px :Pixels ,像素;对应屏幕上的实际像素,是画面中最小的点(单位色块),像素大小没有固定长度值,不同设备上1个单位像素色块大小不同。

这么说可能有点陌生,用屏幕分辨率来说,今年流行起来的“全面屏”分辨率是 21601080,但是你也可以发现,虽然很多全面屏手机分辨率一样,但是明显看得出来屏幕大小不一样,这也解释了“不同设备像素色块大小是不同的”。

pt :1pt=1/72 inch,用于印刷业,非常简单易用;

dpi :Dots Per Inch,每英寸点数;详见ppi

ppi :Pixels Per Inch,每英寸像素数;数值越大显示越细腻。计算式:ppi = 屏幕对角线像素数 / 屏幕对角线长度。

还是举全面屏的例子,分辨率21601080,屏幕大小是59inches,勾股定理可以得到对角线像素数大约是2415,那么ppi = 2415 / 599 = 403

事实上dpi 和 ppi 一定程度上可以划等号,都表示像素密度,计算方式完全一致,只不过使用场景不一样。dpi中的dots点属于打印或印刷等领域,例如drawable 文件对应的就是dpi,而ppi中的pixel属于屏幕显示等领域

dp/dip : Density-independent Pixels,密度无关像素 - 基于屏幕物理密度的抽象单位。1dp等于 160 dpi 屏幕上的dpx,这是 系统为“中”密度屏幕假设的基线密度。在运行时,系统 根据使用中屏幕的实际密度按需要以透明方式处理 dp 单位的任何缩放 。dp 单位转换为屏幕像素很简单:px = dp (dpi / 160)。 例如,在 240 dpi 屏幕上,1 dp 等于 15 物理像素。在定义应用的 UI 时应始终使用 dp 单位 ,以确保在不同密度的屏幕上正常显示 UI。

如果看完文章还是觉得很懵,那么可以直接记住: 1dp单位在设备屏幕上总是等于1/160 inch。

sp :Scale-independent Pixels ,与 dp 单位相似,也会根据用户的字体大小偏好进行缩放。

首先我们放上源码中对尺寸单位的转换

可以看到,输入值类型为dp时,返回 value DisplayMetricsdensity,到这里我们可能会发懵:嗯?不对啊,前面我们不是通过px 和 dp 的换算公式来计算的么,怎么这里就简简单单乘了一个DisplayMetricsdensity?不要慌,我们先看看源码中对DisplayMetricsdensity的介绍。

源码注释中说到“在160dpi的屏幕下,density的值为1,而在120dpi的屏幕下,density的值为075”,我们可以大胆的猜测一下,120dpi下的density=075的原因是120dpi 1 /160dpi=075。实际上,也就是这么回事。我们下面会仔细的分析。

需要补充一下,通常意义上Android 屏幕的密度,指的是像素密度dpi/ppi,对应于源码中的DisplayMetricsdensityDpi。

为什么引入dp?

Android 引入了dp这一单位,使得不论多大屏幕,多大dpi,显示的效果始终保持一致。

但是根据前面我们提到的px与dp的换算公式px = dp (dpi / 160),很显然,由于相同分辨率但不同屏幕大小的设备dpi是不同的,导致px和dp的基本不存在一个固定的换算关系,为了方便屏幕适配,Android设置了6个通用的密度,换算px与dp时采取通用密度计算,而非设备实际的密度。

以下为6种通用密度,以及其最小的分辨率

得到上面通用密度之后,我们换算dp与px多了一种简便方式。前面我们提到Android将mdpi作为基准,此时1px = 1dp,又有px = dp (dpi / 160),所以我们可以很容易的得到以下换算:

还记不记得前面源码中的density属性,实际上DisplayMetricsdensity = dpi / 160 ,表示的就是在某个通用密度下dp与px的换算比(1dp/1px的值)

这部分其实和程序员自身已经关系不大了,毕竟参与工作之后这些都是UI人员的活儿了。不过鉴于现在我还只是一枚在校生,还是记下来以免自己遗漏吧。

建议在xhdpi中作图

原因嘛,首先现在主流分辨率是1080p,以及最近流行起来的全面屏18:9,而xhdpi对应720p,向低dpi兼容自然没问题,即便在xxhdpi中显示,也会有个不错的效果。而如果以19201080作图,显然素材占用的内存很大,而且也会增大应用安装包的大小。

只有一个原则:资源放入对应dpi的文件夹中,Android会机智的加载合适的资源。

以drawable资源为例:

我们平时开发小项目&对UI要求不高时,只使用一套xhdpi的资源就足够了,虽然这可能会导致在hdpi及以下的手机中有些卡顿,因为xhdpi的运行在hdpi及以下的手机上会比较吃内存,不过无伤大雅。

而如果不为资源犯愁时(有UI人员的支持,就是任性),就可以添加所有dpi的资源。当然,重点还是要满足ldpi:mdpi:hdpi:xhdpi:xxhdpi=3:4:6:8:12的规律。

好像说了不少废话,哈哈,大概就这么多吧。

有两种方式:(获取到的大小准确度与手机的类型有关,google手机你还需要加上底部栏)

1

WindowManager wm = (WindowManager) getContext()

getSystemService(ContextWINDOW_SERVICE);

int width = wmgetDefaultDisplay()getWidth();

int height = wmgetDefaultDisplay()getHeight();

2

WindowManager wm = thisgetWindowManager();

int width = wmgetDefaultDisplay()getWidth();

int height = wmgetDefaultDisplay()getHeight();

这个可是涉及到屏幕分辨率的问题啦,首先得获取设备屏幕的大小,然后再去调用与之比较接近的资源,这个资源就是你项目res目录下的那些文件夹唉,比如就有三个文件夹,放置不同尺寸的,下面的布局XML,就用如:layout-240x480,里面的xml对应了相应尺寸的;不知道对你有没有帮助

一些术语

Screen Size 屏幕尺寸:

实际的物理尺寸,以屏幕的对角线为准(包括通知栏?)

将所有的实际尺寸分为四个广义的尺寸:small(小),normal(正常),large(大),extra large(特大)

Density 屏幕密度:

屏幕的屋里面积内的像素数量,通常指dpi(每英寸点数)

small的屏幕密度比normal或large在一个给定的物理面积内具有较少的像素

将所有实际密度分为四个广义的密度:low(低),medium(中等),high(高),extra high(超高)

方向:

从用户的角度来看,屏幕的方向是横向或纵向,也就是屏幕的比例是高或者宽。

Resolution 分辨率:

在屏幕上的像素总数。在支持多个屏幕时,应用程序不直接与分辨率相关,应用程序应该只与屏幕大小和密度相关。

DP(密度无关的像素) Density-independent pixel:

在定义UI布局时应该使用的虚拟像素单元,它用一种密度无关的方式来表达布局尺寸或位置。

Aspect ratio 屏幕长宽比

长宽比是屏幕的物理宽度与物理高度的比例关系。应用程序可以通过使用限定的资源来为指定的长宽比提供屏幕布局资源。

设计和编码

视觉在根据交互原型进行设计的时候,可以考虑以mdpi,也就是320x480为蓝本进行设计,因为Android一般采用dp为单位,而我们设计的时候一般是px为单位的,这个就涉及到一个单位转换的问题,而在mdpi下,px和dp是1:1的关系,这样在标注坐标的时候能够很方便的进行单位转换,例如我们以320x480为蓝本的话,在photoshop测量的间距为10px,我们在给到RD时的坐标可以直接标注为10dp;因为dp的单位是可以程序自己去适配不用dpi屏幕的,所以就算设计三套不同dpi的图,一般也只用对mdpi的设计图进行坐标定位,这个坐标的标注可以用在所有dpi的资源上

Android资源文件

drawable-hdpi里面存放高分辨率的,如WVGA (480x800),FWVGA (480x854)

drawable-mdpi里面存放中等分辨率的,如HVGA (320x480)

drawable-ldpi里面存放低分辨率的,如QVGA (240x320)

默认情况下,当屏幕方面切换时,activity的onCreate()方法会被重新调用,所以可以在其中通过以下代码来读取屏的方向:public void onCreate() {if(thisgetResources()getConfiguration()orientation == ConfigurationORIENTATION_LANDSCAPE) {Logi("info", "landscape");} else if (thisgetResources()getConfiguration()orientation == ConfigurationORIENTATION_PORTRAIT) {Logi("info", "portrait");}}如果在androidmanifestxml中加入配置android:configChanges="orientation|keyboardHidden|navigation当屏幕翻转时,Activity就不会重复的调用onCreate()、onPause()和onResume()而是调用onConfigurationChanged(Configuration newConfig)int screenWidth,screenHeight;WindowManager windowManager = getWindowManager();Display display = windowManagergetDefaultDisplay();screenWidth = displaygetWidth();screenHeight = displaygetHeight();也有另一种方法:DisplayMetrics dm = new DisplayMetrics();getWindowManager()getDefaultDisplay()getMetrics(dm);

以上就是关于Android 关于"尺寸"的那些事(dp,dip,sp,pt,px...)全部的内容,包括:Android 关于"尺寸"的那些事(dp,dip,sp,pt,px...)、怎样获取Android手机屏幕的大小、求大神指导怎样获取Android设备的屏幕尺寸大小等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9653462.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存