关闭

安卓分辨率的相关知识

347人阅读 评论(0) 收藏 举报

一般概念

  1. 分辨率:像素点数,一般描述为『宽*高』,如480*8001080*1920

    一般是宽*高,而不是高*宽

  2. 屏幕大小:手机对角线的物理尺寸,单位inch,如5寸手机指的是对角线的长度为5寸=5*2.54=12.7cm

  3. 密度dpippi:每英尺点数或者每英尺像素),如一部5英寸的手机分辨率是1080*1920,那么他的DPI就是首先算出对角线的长度=2203,然后除以5=440dpi
  4. 系统密度实际密度:上述的440dpi就是实际密度,然后,按照上述的计算,安卓就会有非常非常多dpi的手机,而安卓对界面缩放的时候又依赖这些值,所以每部安卓手机都有一个初始的系统密度(固定值),如:120,160,240,320,480等。 
    安卓对界面元素缩放以来的就是系统密度而不是实际密度:(如图) 
    

    得到实际密度以后,一般会选择一个最近的密度作为系统密度,系统密度是出厂预置的,如440dpi的系统密度就是和他最接近的480dpi,如果是330dpi的手机他的系统密度就是320dpi。但是,我感觉现在很多手机不一定会选择这些值作为系统密度,而是选择实际的dpi作为系统密度,这就导致了很多手机的dpi也不是在这些值内。

  5. dp:像素无关的密度,比如1dp在320*480的手机和480*800的手机上看着长度差不多 

  6. sp:像素无关的尺寸,这样在设置里面调节字号的时候,文字会随之变大变小。

dp与px的转换:

安卓中以160dpi的手机密度为基准,即320*480这个屏幕,这个屏幕时,1dp=1px 
那么在480*800的屏幕中,1dp=1.5px 
最后得出了下面这张表: 

事实上,Android中,下面的0.75,1,1.5,2,3才是屏幕密度(density)。而120,160,240,320,480是屏幕密度dpi(densityDpi),可以通过下面的方法获得系统的这些属性:

  1. // 获取屏幕密度(在Context环境下,比如在Activity中执行这些代码或者传入Context对象去获得DisplayMetrics)
  2. DisplayMetrics dm = getResources().getDisplayMetrics();
  3. //getWindowManager().getDefaultDisplay().getMetrics(dm);
  4. float density = dm.density; // 屏幕密度(像素比例:0.75/1.0/1.5/2.0,3.0,4等)
  5. int densityDPI = dm.densityDpi; // 屏幕密度(这里是系统密度)(每寸像素:120/160/240/320,480,640等)
  6. float xdpi = dm.xdpi; //这两个是水平和垂直方向上的dpi,如果要计算水平和垂直方向上的实际dp值,可以通过后面`屏幕的宽高差异`中的内容计算。不过你倒是可以通过这两个值大致计算屏幕的宽和高的英寸
  7. float ydpi = dm.ydpi;
  8. Log.e(TAG, " DisplayMetrics: " + "xdpi=" + xdpi + "; ydpi=" + ydpi);
  9. Log.e(TAG, " DisplayMetrics: " + "density=" + density + "; densityDPI=" + densityDPI);
  10. screenWidth = dm.widthPixels; // 屏幕像素宽(像素,如:480px)
  11. screenHeight = dm.heightPixels; // 屏幕像素高(像素,如:800px)
  12. Log.e(TAG, " DisplayMetrics" + "screenWidth=" + screenWidth + "; screenHeight=" + screenHeight);

sp与px

当系统字号为普通时,sp和px的尺寸换算与dp与px的换算是一直的,如在720*1280的ps画布中,文字大小是24px,那么这个蚊子大小就是12sp

建议在xdhpi中作图: 
因为现在主流的分辨率都是1080*1920,所以建议在720*1280的画布上设计,不是设计ROM的话,用这个分辨率,内存消耗不是太多而且也比较美观,而且计算简单,1dp=2px

屏幕的宽高差异:

例如,在上面图示中的标准系统密度中:

  1. 160dpi(320*480)240dpi(480*800)的屏幕宽度都是320dp (320px宽度是1dp=1px,480px宽度是1dp=1.5px) 
    320dpi(720*1280)480dpi(1080*1920)的屏幕宽度都是360dp ( 720/2 = 360, 1080/3 = 360dp )

    1. 一个手机的dp宽度是可以计算的:例如:1080*1920的手机,如果是5.2寸的手机,那么他的dpi就是420dpi,所以对应的屏幕宽度就是1080/(420/160)=411dp,他的公式就是屏幕宽度/DPI ,高度也是一样的。这个dpi是系统dpi,但是很多手机的系统dpi就是实际dpi。
    2. 系统密度主要是用来做资源和组件缩放的,比如你的系统密度dpi是480dp,系统密度就是3.0,对应的drawable资源文件家也就是xxhdpi,那么系统就会优先选择这个限定符下的资源;另外,系统在选择缩放资源的时候也是以对应的倍率(480dpi对应的倍率是3,也就是1dp=3px),后面有讨论不同的资源文件夹中的drawable的实际大小中有一些讨论。但是,如果按照实际密度,每个手机的1dp对应的px差别都会很大,这样就不方便做设计。
    3. 所以说,不同手机的宽度差别还是很大的,但是至少应该是320dp+了吧,往大了有四百多,这里仅仅说一般的手机啊。所以说,现在差的可不仅仅是40dp啊。所以水平方向设置组件的宽度时,如果是比较小的按钮就直接设置宽度的dp,如果要设置基本上等于宽度的组件,就match-parent了,也不要设置什么320dp之类的。
    4. 在我的honor 6上,手机宽度是360dp,他的density=3.0,densityDpi=480dpi,这个值就不是实际dpi,但是屏幕宽度dp值是通过这个系统密度计算的(360dp=1080/3),所以我猜测组件的缩放的确是通过系统密度进行的,但是很多手机的系统密度dpi就是实际dpi,所以对应的density就会不同,从而导致宽度不同。比如,我又试了小米Note手机,他是1080*1920,5.7寸的手机,他的densityDpi(也就是系统密度)=440,而没有设置为480dpi,导致他的density=2.75,所以他的宽度就是 392dp=1080/2.75. 其实这个440dpi也不是他手机的实际dpi,实际dpi经过计算可以得知=386dpi,所以。这些手机设置dpi不一定是前面列表中提到的哪几种值,也不一定是实际密度。
  2. 高度上:宽高比从2:3(320*480), 3:5(480*800), 9:16 (720*1280 或 1080*1920)都有,高度的dp数比例差异很大,为了针对不同的分辨率,可以通过文件家名进行不同的设置,如layout-w320dp,layout-854*480

几个资源的文件夹:

在720*1280中做的图片,要让开发人员放到drawable-xhdpi的资源文件夹中,这样才可以正确显示 
个人认为一套素材就可以了,可以测试一下在低端手机上运行流畅度。可以根据需要提供部分mdpi的图片素材,因为xhdpi中的图片运行在mdpi的手机上会比较占内存。 
 

如果你要把一个高2px的分割线做成9.png图片,想让细线在不同密度中都是2px,而不是被安卓根据密度进行缩放,可以放到drawable-nopdi,这个资源文件夹中的图片,将按照实际像素显示,不会被安卓根据密度进行缩放。

不同的资源文件夹中的drawable实际的大小

下面是一张图片: 
 
然后我们设置ImageView如下:

  1. <ImageView
  2. android:layout_width="120dp"
  3. android:layout_height="85dp"
  4. android:layout_below="@id/btn2"
  5. android:scaleType="matrix"
  6. android:src="@drawable/hello" />

他的尺寸是120px*85px 
如果只把它放到drawable下面,但是我们的手机是xhdpi的,那么这个图片不缩放的长宽就是120dp*85dp. 因为系统把这个图片当做是mdpi,也就是1dp=1px
最后显示的结果如下: 

  1. 可以看到图片刚好充满View
  2. 当然,要知道该图片的实际像素大小,比如,在xxhdpi的手机(他的密度是3.0)上,1dp=3px,所以,这张图片会被放大三倍,也就是它在这个手机上实际像素为360px*255px,对应的占用内存的大小大约是 360*255*4/1024/1024=0.35M.

如果只把它放到drawable-xhdpi下面的话,他默认的长宽就约是60dp*42dp,因为这个位置下面的素材1dp=2px 

  1. 可以看到图片刚好占了View的四分之一,水平垂直各一半。
  2. 对于在一个xxhdpi的手机上,1dp=3px,所以他的实际大小会被放大1.5倍((x/2)*3),其实可以通过我们前面dp和px转换那一节的表格中可以得到,这个图片在density=3.0的手机上的实际大小是192px*127px,对应的内存占用也可以算出来大约是0.09M

如果只放到drawable-xxhdpi下面的话,他默认的长宽就是40dp*28dp 

可以看到图片刚好占了View的九分之一,水平垂直各1/3 
他的实际大小就是原大小120px*85px,他的内存占用大约是0.039M

因此可以看出,如果我们的手机是高分辨率,而素材在低分辨率下的话,图片就会显得比较大,而且内存占用也比较高。所以,一般的推荐是做一份xhdpi的素材,因为现在xddpi的手机比较广泛,而且iPhone手机也基本在这个类别下,方便设计师统一设计。

另外,发现了一篇比较好的博文,讲了其他的一些内容,推荐阅读: 
获得屏幕物理尺寸、密度及分辨率 
另外刚发现一篇对drawable内存大小占用的实验讨论: 
关于Android中图片大小、内存占用与drawable文件夹关系的研究与分析

参考: 
站酷/UI设计师不可不知的安卓屏幕知识 
手机屏幕的实际密度和系统密度,及其计算方法

原文

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:92056次
    • 积分:1555
    • 等级:
    • 排名:千里之外
    • 原创:16篇
    • 转载:295篇
    • 译文:0篇
    • 评论:6条