px

表示屏幕的物理像素,例如 1080×1920

densityDpi

简称dpi,我们常说的像素密度,表示1英寸上对应有多少个像素,例如 160dpi、320dpi、440dpi、480dpi.
以1080×1920的5英寸手机为例:
宽:1080像素
高:1920像素
对角线(5英寸):根据勾股定理算出大约2203像素
每英寸上大约有:440像素 = 2203/5
所以这个手机的像素密度是440dpi

dp

dip的别称,dp是Android上为了适配不同屏幕设备而定义的一种抽象单位,1dp可以理解为屏幕上的一个点,这个点在不同屏幕分辨率上占用的像素不一样,比如在屏幕分辨率高的设备上占用更多像素,在分辨率小的设备上占用更少的像素,从而让它整体上来看显示的比例相对屏幕大小是一样的

density

与densityDpi类似,densityDpi表示1英寸上对应有多少个像素(对应屏幕物理像素密度); 而density则表示1dp上有多少个像素,可以理解为dp密度(对应抽象的屏幕密度);它可以用于dp和px之间转换
计算公式:density = px/dp;
它与densityDpi之间的关系是固定的:density = densityDpi / 160
例如:
当densityDpi=160时,density=1,也就是1英寸上有160个像素,1dp就代表1像素
当densityDpi=320时,density=2,也就是1英寸上有320个像素,1dp就代表2像素

为什么dip用160作为标准呢?主要有两个原因

  • Android 主流设备的 dpi 有:120 dpi、160 dpi、240 dpi、320 dpi、440dpi、480dpi;在开发过程中,因为需要对多个主流设备尺寸适配,在以某个dpi标准设计好后,需要转换成其他主流dpi尺寸;上面主流dpi它们分别是160的0.75、1、1.5、2、2.75、3倍,也就是它们倍数是有限小数;
    而如果假设以 240 dpi 作为标准,它们分别是240的0.5、0.66666666666…、1、1.3333333…、1.8333…、2倍,也就是算出来没有那么精准,误差更大
  • 在Google的官方文档中有给出了解释,因为第一款Android设备(HTC的T-Mobile G1)是属于160dpi的

小结

  • px和densityDpi代表真实的物理屏幕尺寸和密度
  • dp和density表示Android中为了让不同屏幕尺寸上显示效果接近一致而抽象出来的,表示抽象的屏幕尺寸和密度

扩展

获取屏幕宽高和dpi以及density

//kotlin
var displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getRealMetrics(displayMetrics) //从WindowManager获取DisplayMetricsdisplayMetrics = resources.displayMetrics //从Resources获取DisplayMetricsdisplayMetrics.widthPixels //屏幕宽度
displayMetrics.heightPixels //屏幕高度
displayMetrics.density //dp和px比例
displayMetrics.densityDpi //像素密度val point = Point()
windowManager.defaultDisplay.getRealSize(point);
point.x //屏幕宽度
point.y //屏幕高度

px和dp互转

  • 之所以要将结果+0.5再转int,是因为float类型直接转int会向下取整,加上0.5再转就能达到四舍五入效果;例如:
    1.3直接转int后结果是1,加上0.5后是1.8,再转int后结果也还是1
    1.6直接转int后结果是1,加上0.5后是2.1,再转int后就是四舍五入效果2了
fun dp2px(context: Context, dpValue: Float): Int {val density = context.resources.displayMetrics.densityreturn (dpValue * density + 0.5).toInt()
}
fun px2dp(context: Context, pxValue: Float): Int {val density = context.resources.displayMetrics.densityreturn (pxValue / density + 0.5).toInt()
}

屏幕适配方案

fun setCustomDensity(activity :Activity){val designWidthDp = 360 //假设设计图按照宽度360dp大小进行设计var displayMetrics = activity.resources.displayMetrics//计算出每个dp上有多少个像素,也就是density值val targetDensity = displayMetrics.widthPixels / designWidthDp// 重新计算dpi值val targetDensityDpi = targetDensity * 160displayMetrics.density = targetDensity.toFloat()displayMetrics.densityDpi = targetDensityDpi//Application的DisplayMetrics也要设置displayMetrics = activity.application.resources.displayMetricsdisplayMetrics.density = targetDensity.toFloat()displayMetrics.densityDpi = targetDensityDpi
}

为什么要根据设计图dp宽度调整density值?

dp在Android只是个抽象单位,最终还是会根据density转换成px值;
假如按照屏幕宽度540dp设计UI图,绘制一条长度为540dp的线条,代码中设置该线条长度为540dp

  • 在设备1上:
    分辨率1080×1920
    转换dp: 540dp x 960dp
    像素密度:320dpi
    density = 2
    线条实际长度:540dp * 2(density) = 1080px
    显示效果:长度刚好是屏幕的宽度,与设计图效果一致

  • 在设备2上:
    分辨率:1080×1920
    转换dp: 1080dp x 1920dp
    像素密度:160dpi
    density = 1
    线条实际长度:540dp * 1(density) = 540px
    显示效果:长度只有屏幕宽度的一半,与设计图差别很大

  • 经过适配重新调整设备2的DisplayMetrics参数后:
    newDensity=1080(屏幕分辨率)/540(设计图屏幕宽度)=2
    线条实际长度:540dp * 2(newDensity) = 1080px
    显示效果:长度刚好是屏幕的宽度,与设计图效果一致

Android px density densityDpi dp 之间的关系和区别相关推荐

  1. 一篇文章看明白 Android 图形系统 Surface 与 SurfaceFlinger 之间的关系

    Android - SurfaceFlinger 图形系统 相关系列 一篇文章看明白 Android 系统启动时都干了什么 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制 一篇文 ...

  2. java map与set的区别_java 集合(list,set,map)三者之间的关系和区别

    原 java 集合(list,set,map)三者之间的关系和区别 一:先上一张关系图,让大家看的更明白. 备注:其中红色部分为实现,其他地方均为接口. 二:各自的特点. List 有序,可重复Arr ...

  3. sql语句和java的关系_java中Statement 与 PreparedStatement接口之间的关系和区别

    Statement 和 PreparedStatement之间的关系和区别. 关系:PreparedStatement继承自Statement,都是接口 区别:PreparedStatement可以使 ...

  4. 栈,队列和链表三者之间的关系与区别

    最近一直在学习算法,刷算法题,但是自从大学毕业以来,数据结构的知识都还给老师了,只会个数组,所以前期刷的题目也都是有关数组的 最近跟着小册重学了一遍数据结构,今天就记录一下栈,队列和链表三者之间的关系 ...

  5. 详解RTK、RTD、SBAS、WAAS、PPP、PPK广域差分等技术之间的关系与区别。

    RTK与RTD的区别,一个是载波相位差分.一个是码差分,并且RTK的定位精度要高一些. RTK与PPK的区别,一个是实时提供数据信息,一个是事后处理. WAAS是SBAS系统一个具体的实例,包含在SB ...

  6. 详解RTK,RTD,SBAS,WAAS,PPP,PPK,广域差分等技术之间的关系与区别

    RTK与RTD的区别,一个是载波相位差分.一个是码差分,并且RTK的定位精度要高一些. RTK与PPK的区别,一个是实时提供数据信息,一个是事后处理. WAAS是SBAS系统一个具体的实例,包含在SB ...

  7. 安卓Android和Java语言的异同、关系和区别

    安卓Android和Java语言的异同.关系和区别,安卓Android是一种以Linux为基础的开放源码操作系统,主要使用于便携设备.2011年第一季度,安卓在全球的市场份额首次超过塞班系统,跃居全球 ...

  8. UIView 的 alpha、hidden 和 opaque 属性之间的关系和区别

                     UIView 的 alpha.hidden 和 opaque 属性之间的关系和区别 UIView的这几个属性让我困惑了好一阵子,通过翻看官方文档和stackoverf ...

  9. CGI,FastCGI和PHP-FPM之间的关系和区别

    CGI,FastCGI和PHP-FPM之间的关系和区别. 什么是CGI? 早期的web server只可以处理简单的静态web文件,但是随着技术的发展出现动态语言如PHP,Python.PHP语言交给 ...

最新文章

  1. 压缩和归档及vi的使用
  2. 求解稀疏优化问题——增广拉格朗日方法+半光滑牛顿法
  3. 有一种爱,永远也无法逾越
  4. android wifi调试
  5. 【Python】纯代码通过神经网络实现线性回归的拟合
  6. html代码中本地路径里斜杠 / 和反斜杠 \ 的区别
  7. 语言程序设计第4版黄洪艺_谭浩强《C程序设计》第4版网授精讲班【教材精讲+考研真题串讲】视频网课讲义课程资料...
  8. GTK+ tutorial
  9. Entity Framework Core 3.1 和 Entity Framework 6.4 发布
  10. TOMM2018_Unsupervised Person Re-identification: Clustering and Fine-tuning
  11. nginx 隐藏目录_Nginx学习之简单练习反向代理和负载均衡
  12. excel 直接查询企查查数据_EXCEL在多表中查询数据(函数中引用工作表的办法)...
  13. 值栈ValueStack的原理与生命周期
  14. ORB-SLAM(一)简介
  15. 抖音protobuf分析
  16. 【Windows账户名修改】win10家庭版更改中文账户名
  17. 714. 买卖股票的最佳时机含手续费
  18. 计算机中的八卦知识,论八卦与电脑的关系
  19. 无法安装net framework 3.5 的解决方法
  20. 如何打造一个可躺赚的网盘项目,每天只需要2小时

热门文章

  1. Hugging Face PEFT 调优实战附代码
  2. 几个小步骤教你线上使用浪潮webblos做raid---简单明了!
  3. vue 监听返回按钮
  4. 《Miss Talk》第03期:对话学霸君吴凯
  5. 电子游戏究竟能对人造成什么影响?——近几年内基于ERP分析游戏影响的研究解读(一)
  6. android输入法状态监听 js,中文拼音输入法在input监听的问题(监听字节数)
  7. 【观察】小米上市后首次发布财报 同比增长75.4%背后的秘密
  8. mysql 钩子程序_20200319 代码发布之任务发布钩子脚本
  9. 互联网时代,我们都在裸泳!
  10. invalid openid hint