1.屏幕适配的相关知识
首先扔出一个问题,为什么图片会被拉伸变形?
Android中根据DensityDpi的不同将设备分成了多个显示级别:
ldpi | mdpi | hdpi | xhdpi | xxhdpi | xxxhdpi | |
---|---|---|---|---|---|---|
dpi | 0-120 | 120-160 | 160-240 | 240-320 | 320-480 | 480-640 |
DensityDpi计算公式 = (根号下 屏幕宽度²+屏幕高度²)/屏幕英寸;
DensityDpi 定义:每英寸上的像素点个数;
Android 中使用DisplayMetrics中的densityDpi字段表示该值,文档中也常用dpi来简化或者指代densityDpi;
dpi可以使用DisplayMetrics获取,根据屏幕宽高计算的实际值可能跟获取配置的dpi的值不一样,部分厂商会向贴近的值靠拢。
Density-Independent pixel 简称为 dip 或者 dp,它表示与密度无关的像素
px = dp * (dpi/160); https://developer.android.google.cn/training/multiscreen/screendensities?hl=en
由此可见100 dp单位的控件,在xhpdi的手机下会占200像素,在mdpi的手机下占100像素,但在手机屏幕上的占比一致,这也就是dp单位控件可以适配屏幕的原因;
官方文档注解:这个dp值在dpi为160的时候,一个px就等于一个dp。
那么为什么会有这么多的屏幕适配文章与技术出现呢?dp不可以适配么
原因就是:分辨率太多 基比不一样啊
ldpi | mdpi | hdpi | xhdpi | xxhdpi | xxxhdpi | |
---|---|---|---|---|---|---|
dpi | 0-120 | 120-160 | 160-240 | 240-320 | 320-480 | 480-640 |
屏幕分辨率 | 240*320 | 320*480 | 480*800 | 720*1280 | 1080*1920 | 1440*2560 |
100dp单位在屏幕显示像素 | 75px | 100px | 150px | 200px | 300px | 400px |
100dp在屏幕横向占比 | 0.3125 | 0.32 | 0.3125 | 0.2777 | 0.2777 | 0.2777 |
100dp在屏幕纵向占比 | 0.2343 | 0.48 | 0.1875 | 0.1562 | 0.1562 | 0.1562 |
上图表达的是什么?就是同样100dp单位的控件,在整个屏幕的横向占比不一致,所以你的dp控件会在手机上表现不一,而慢慢的随着版本的迭代,这个规则好像有在统一,所以绝大部分情况下,dp还是可以适应你的屏幕适配需求的。
TypedValue与drawable的对应关系;
As工程下有多个drawable文件,每套文件夹都对应了不同的分辨率,不同的文件密度;
根据resourece 获取图片资源时会找到对应文件下的dpi;
TypedValue 源码中的 applyDimension 计算px
drawable图片加载过程
TypedValue 会获取图片所在文件位置密度,同时也会获取系统像素密度,在BitmapFactory decodeResource时 计算过缩放比 系统像素密度/文件所在位置像素密度,这个scale比值被用在了BitmapFactory解析资源图片大小,和画布缩放上,这也就是像素失真的原因(一张图片在不同drawable文件夹下,被加载在相同手机上占用的字节数不一样,如果图片所在文件目录dpi低于运行手机的dpi,图片就会被放大,相反,如果放在高于手机像素密度的文件夹中,图片就会缩小)。