dp的定义原理和dp,px,pt,sp之间的区别
2015-11-23 11:47
232 查看
与分辨率无关的度量单位可以解决这一问题。Android支持下列所有单位。
px(pixel 像素):屏幕上的点,一般HVGA代表320x480像素。
in(inch 英寸):长度单位。
mm(毫米):长度单位。
pt(磅):1pt=1/72英寸,用于印刷业,非常简单易用;。
dp(dip : device independent pixels(设备独立像素)):一种基于屏幕密度的抽象单位。在每英寸160点的显示器上,1dp = 1px。
dpi:与dp相同,多用于android/ophone示例中。
sp(与刻度无关的像素):与dp类似,但是可以根据用户的字体大小首选项进行缩放。
QVGA : 分辨率为 240*480 (Quarter VGA即四分之一)
HVGA :分辨率为 320*480 ( Half-size VGA即一半)
VGA : 分辨率为 640*480 (全称Video Graphic Array)
WVGA : 分辨率为 800*480 (Wide VGA 很多网页的宽度都是800,所以WVGA的手机屏幕会更加适合于浏览网页)
FWVGA :分辨率为 854*480 手机c8813就是
1.为什么每英寸160点的显示器上,1dp = 1px?
在这篇博客中的这个提问有瑕疵
答:这个在Google的官方文档中有给出了解释,因为第一款Android设备(HTC的T-Mobile G1)是属于160dpi的。
The generalized sizes and densities are arranged around a baseline configuration that is a normal size and mdpi(medium) density. This baseline is based upon the screen configuration for the first Android-powered device, the T-Mobile G1, which has an HVGA screen (until Android 1.6, this was the only screen configuration that Android supported).
为什么说是属于呢?
T-Mobile G1的DPI,其实它准确的DPI不等于160,G1的配置信息如下:
屏幕尺寸:3.2 寸(8.1 厘米)
分辨率:320 x 480(HVGA)
DPI(Dots Per Inch)为每英寸像素点的个数,
英寸是一个物理单位,大家平常说的手机屏幕4.3英寸,4.5英寸指的是屏幕对角线的长度,如下图所示:
公式为: dpi = 屏幕对角线像素数(px) / 屏幕对角线长度(in)
分辨率480 x 800,屏幕尺寸4.3英寸和分辨率540 x 960,屏幕尺寸4.5英寸的DPI分别是:
如果按照这样的计算方式的话,T-Mobile G1应该为180dpi,使用计算器,计算结果为180.277564dpi。
计算出来的结果是180而不是160,那为什么不直接用180作为基准(mdpi)而是160呢?180上下不好做适配,但是160无论是乘以0.5/2/1.5都很好适配,这就是为什么是属于而不是等于。
Android其实为了不至于为每一个设备制造商做适配(其实资源文件的分包就算适配了:drawable-hdpi,drawable-ldpi),将不同屏幕大小和不同dpi的设备大致划分为四类,如下图:
大家可以看到T-Mobile G1的参数属于mdpi区域的,以上就是取160dpi作为基准的原因。在编程过程中获得的density,与自己手动计算出来的dpi是不一样的,因为这里进行了分类,所以不同dpi(系统自定的)设备上,比例缩放有一点点差异
2.如果设定宽高为厘米,或者英寸之类的物理单位,屏幕根据dpi的大小来计算要显示多少像素才能达到这个物理单位,不是更好?为什么要引入dp?
如果有兴趣可以看一下这个类的源码(网址):GrepCode: android.util.DisplayMetrics (.java) ,这个类中有很详细的dpi相关的成员函数和变量,下面的代码是在开发时获取dpi的代码,
(1)我先回答前半部分,“如果设定宽高为厘米,或者英寸之类的物理单位,屏幕根据dpi的大小来计算要显示多少像素才能达到这个物理单位,不是更好?”
答:我认为设置宽高为厘米/英寸,然后先通过上面代码动态计算dpi的值,然后再根据计算出的dpi计算出显示控件需要的宽和高是可行的,但是绝对不是更好,而是非常差,因为开发的原则遵循的是界面设计和功能逻辑分离,在程序中每次都首先需要计算一下dpi才能设定其他控件的宽高属性是很不友好的,你想想,你启动了某个程序,它界面一直出不来,后台还在计算着DPI,用户体验也不会好,超过5s估计就被当作ANR给kill掉了。
(2)为什么要引入dp?
答:dp实际是dip(density independent pixel),独立密度像素,意思就是与density密度(dpi)无关,我使用dp作为单位设置控件,不管你什么屏幕大小,多大的dpi,显示的效果始终保持一致。假如我们不引入dp,还是使用原始的px,现在我们需要在手机屏幕上绘制一条直线,在160dpi(每英寸160个像素点),而宽度是1英寸的手机上做开发和测试工作,我们设置这条直线长度是160px(占据160个像素点),也就是直线长度正好是手机的宽度,开发工作完成,我们把app发布到市场上,这时候JJ Ying用他同样宽度1英寸,但是240dpi的手机安装了这个app,他能不抓狂!本该长度有屏幕这么宽的线视觉上只有原来的2/3,如果整个UI都使用px作为单位,就会有如下的效果。
Example application without support for different densities, as shown on low, medium, and high density screens.
上面这张图来自Google的开发网站。如果引入dp这个单位,这种问题就不会发生了,还是以上面的例子说明,如果在160dpi的设备上使用的是160dp,无论移植到240,120dpi上显示效果都是一致的。效果如下图:
为了使用户界面能够在现在和将来的显示器类型上正常显示,建议大家始终使用sp作为文字大小的单位,将dip作为其他元素的单位。当然,也可以考虑使用矢量图形,而不是用位图
dp:A dp is a density-independent pixel that corresponds to the physical size of a pixel at 160 dpi(dots per inch:每英寸点数).
dp也就是dip:device independent pixels(设备独立像素)
dp是一种与密度无关的像素单位,在每英寸160点的屏幕上,1dp = 1px
px和dp的换算公式px = dp * (dpi / 160)
不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素
sp:An sp is the same base unit, but is scaled by the user’s preferred text size (it’s a scale-independent pixel), so you should use this measurement unit when defining text size (but never for layout sizes).
scaled pixels(刻度像素). 主要用于定义字体的大小,而从来不再layout上使用
px:pixels(像素). 不同设备显示效果相同,一般我们HVGA代表320x480像素,这个用的比较多
总结:dp也就是dip。这个和sp基本类似。如果设置表示长度、高度等属性时可以使用dp或sp。但如果设置字体,需要使用sp。dp是与密度无关,sp除了与密度无关外,还与scale无关。
如果屏幕密度为160,这时dp和sp和px是一样的。1dp=1sp=1px,但如果使用px作单位,如果屏幕大小不变(假设还是3.2寸),而屏幕密度变成了320。那么原来TextView的宽度设成100px,在密度为320的3.2寸屏幕里看要比在密度为160的3.2寸屏幕上看短了一半。
但如果设置成100dp或100sp的话。系统会自动将width属性值设置成200px的。也就是100 * 320 / 160。其中320 / 160可称为密度比例因子。也就是说,如果使用dp和sp,系统会根据屏幕密度的变化自动进行转换.
附:px 和 dp 互转换
px(pixel 像素):屏幕上的点,一般HVGA代表320x480像素。
in(inch 英寸):长度单位。
mm(毫米):长度单位。
pt(磅):1pt=1/72英寸,用于印刷业,非常简单易用;。
dp(dip : device independent pixels(设备独立像素)):一种基于屏幕密度的抽象单位。在每英寸160点的显示器上,1dp = 1px。
dpi:与dp相同,多用于android/ophone示例中。
sp(与刻度无关的像素):与dp类似,但是可以根据用户的字体大小首选项进行缩放。
QVGA : 分辨率为 240*480 (Quarter VGA即四分之一)
HVGA :分辨率为 320*480 ( Half-size VGA即一半)
VGA : 分辨率为 640*480 (全称Video Graphic Array)
WVGA : 分辨率为 800*480 (Wide VGA 很多网页的宽度都是800,所以WVGA的手机屏幕会更加适合于浏览网页)
FWVGA :分辨率为 854*480 手机c8813就是
1.为什么每英寸160点的显示器上,1dp = 1px?
在这篇博客中的这个提问有瑕疵
答:这个在Google的官方文档中有给出了解释,因为第一款Android设备(HTC的T-Mobile G1)是属于160dpi的。
The generalized sizes and densities are arranged around a baseline configuration that is a normal size and mdpi(medium) density. This baseline is based upon the screen configuration for the first Android-powered device, the T-Mobile G1, which has an HVGA screen (until Android 1.6, this was the only screen configuration that Android supported).
为什么说是属于呢?
T-Mobile G1的DPI,其实它准确的DPI不等于160,G1的配置信息如下:
屏幕尺寸:3.2 寸(8.1 厘米)
分辨率:320 x 480(HVGA)
DPI(Dots Per Inch)为每英寸像素点的个数,
英寸是一个物理单位,大家平常说的手机屏幕4.3英寸,4.5英寸指的是屏幕对角线的长度,如下图所示:
公式为: dpi = 屏幕对角线像素数(px) / 屏幕对角线长度(in)
分辨率480 x 800,屏幕尺寸4.3英寸和分辨率540 x 960,屏幕尺寸4.5英寸的DPI分别是:
如果按照这样的计算方式的话,T-Mobile G1应该为180dpi,使用计算器,计算结果为180.277564dpi。
计算出来的结果是180而不是160,那为什么不直接用180作为基准(mdpi)而是160呢?180上下不好做适配,但是160无论是乘以0.5/2/1.5都很好适配,这就是为什么是属于而不是等于。
Android其实为了不至于为每一个设备制造商做适配(其实资源文件的分包就算适配了:drawable-hdpi,drawable-ldpi),将不同屏幕大小和不同dpi的设备大致划分为四类,如下图:
大家可以看到T-Mobile G1的参数属于mdpi区域的,以上就是取160dpi作为基准的原因。在编程过程中获得的density,与自己手动计算出来的dpi是不一样的,因为这里进行了分类,所以不同dpi(系统自定的)设备上,比例缩放有一点点差异
2.如果设定宽高为厘米,或者英寸之类的物理单位,屏幕根据dpi的大小来计算要显示多少像素才能达到这个物理单位,不是更好?为什么要引入dp?
如果有兴趣可以看一下这个类的源码(网址):GrepCode: android.util.DisplayMetrics (.java) ,这个类中有很详细的dpi相关的成员函数和变量,下面的代码是在开发时获取dpi的代码,
[code]DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); iDensity = (int)( metrics.density * 160 );
(1)我先回答前半部分,“如果设定宽高为厘米,或者英寸之类的物理单位,屏幕根据dpi的大小来计算要显示多少像素才能达到这个物理单位,不是更好?”
答:我认为设置宽高为厘米/英寸,然后先通过上面代码动态计算dpi的值,然后再根据计算出的dpi计算出显示控件需要的宽和高是可行的,但是绝对不是更好,而是非常差,因为开发的原则遵循的是界面设计和功能逻辑分离,在程序中每次都首先需要计算一下dpi才能设定其他控件的宽高属性是很不友好的,你想想,你启动了某个程序,它界面一直出不来,后台还在计算着DPI,用户体验也不会好,超过5s估计就被当作ANR给kill掉了。
(2)为什么要引入dp?
答:dp实际是dip(density independent pixel),独立密度像素,意思就是与density密度(dpi)无关,我使用dp作为单位设置控件,不管你什么屏幕大小,多大的dpi,显示的效果始终保持一致。假如我们不引入dp,还是使用原始的px,现在我们需要在手机屏幕上绘制一条直线,在160dpi(每英寸160个像素点),而宽度是1英寸的手机上做开发和测试工作,我们设置这条直线长度是160px(占据160个像素点),也就是直线长度正好是手机的宽度,开发工作完成,我们把app发布到市场上,这时候JJ Ying用他同样宽度1英寸,但是240dpi的手机安装了这个app,他能不抓狂!本该长度有屏幕这么宽的线视觉上只有原来的2/3,如果整个UI都使用px作为单位,就会有如下的效果。
Example application without support for different densities, as shown on low, medium, and high density screens.
上面这张图来自Google的开发网站。如果引入dp这个单位,这种问题就不会发生了,还是以上面的例子说明,如果在160dpi的设备上使用的是160dp,无论移植到240,120dpi上显示效果都是一致的。效果如下图:
为了使用户界面能够在现在和将来的显示器类型上正常显示,建议大家始终使用sp作为文字大小的单位,将dip作为其他元素的单位。当然,也可以考虑使用矢量图形,而不是用位图
dp:A dp is a density-independent pixel that corresponds to the physical size of a pixel at 160 dpi(dots per inch:每英寸点数).
dp也就是dip:device independent pixels(设备独立像素)
dp是一种与密度无关的像素单位,在每英寸160点的屏幕上,1dp = 1px
px和dp的换算公式px = dp * (dpi / 160)
不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素
[code]<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/clickme" android:layout_marginTop="20dp" />
sp:An sp is the same base unit, but is scaled by the user’s preferred text size (it’s a scale-independent pixel), so you should use this measurement unit when defining text size (but never for layout sizes).
scaled pixels(刻度像素). 主要用于定义字体的大小,而从来不再layout上使用
[code]<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20sp" />
px:pixels(像素). 不同设备显示效果相同,一般我们HVGA代表320x480像素,这个用的比较多
总结:dp也就是dip。这个和sp基本类似。如果设置表示长度、高度等属性时可以使用dp或sp。但如果设置字体,需要使用sp。dp是与密度无关,sp除了与密度无关外,还与scale无关。
如果屏幕密度为160,这时dp和sp和px是一样的。1dp=1sp=1px,但如果使用px作单位,如果屏幕大小不变(假设还是3.2寸),而屏幕密度变成了320。那么原来TextView的宽度设成100px,在密度为320的3.2寸屏幕里看要比在密度为160的3.2寸屏幕上看短了一半。
但如果设置成100dp或100sp的话。系统会自动将width属性值设置成200px的。也就是100 * 320 / 160。其中320 / 160可称为密度比例因子。也就是说,如果使用dp和sp,系统会根据屏幕密度的变化自动进行转换.
附:px 和 dp 互转换
[code]package com.hujl.util; import android.content.Context; public class DensityUtil { /** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } /** * 根据手机的分辨率从 px(像素) 的单位 转成为 dp */ public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } }
相关文章推荐
- 将maven项目发布到nexus
- CountDownLatch(倒计时计数器)使用说明
- cocos2d-x + Lua接入iOS原生SDK的实现方案[转]
- linux命令学习:echo详解,格式化输出,不换行输出
- 配置JDK————找不到或无法加载主类
- Moto Droid4 刷机包 CM12.1增强版 RC5.6 安卓5.1.1 归属和T9 h2os主题化 应用锁等
- TOMCAT中文问题,解决(全)
- iOS 字符串处理
- 数据库的范式
- 开发人员和测试人员面对面沟通的重要性
- CLR中的程序集加载
- URL访问网站的过程(三次握手、四次挥手),发送RST包的四种情况,常用协议
- tvOS多层图片的使用
- php面向对象类中常用的魔术方法
- Gradle build设置自动log开关
- PAM-Linux可插拔认证模块的基本概念与架构
- 配置Maven使用本地lib文件夹
- ACE内存管理之ACE_Cached_Allocator类详解
- lua绑定c++的时候常见得错误
- android activity监听加载完毕事件