今日头条适配方案心得

目的:搞成和设计图一样的比例,适配的终极目的就是按比例适配

本质就是这个公式:

px = density * dp;

每个手机的像素数量是不变的,所以通过改变1dp所占的像素个数(像素密度),达到使不同设备的横向dp值相等,从而实现了比例适配

 

今日头条最终:在某些条件下保证比例相等例(成比例):

注意这个比例相等是指控件在设备上的大小和设备的比例,在不同设备上相同,同时也和设计图上的控件和设计图的比例相等。
在两个设备的总dp值相等时,可以达到等比例的效果(猜测一开始谷歌也是想在出产手机的时候也按这个标准),所以今日头条就改变density来使总dp值相等来达到比例适配。

那为什么两个设备的dp值相等了就成比例了呢?

只有我们开发时用的是dp,那两个设备的dp值相等时才能达到了成比例的效果,我们设置1dp就是整个设备的1/dp值,例如设备的dp值是360dp,因为dp和长度挂钩,那1dp就是1/360设备的长度.

 

今日头条的做法是在同一个dp值下如360dp,改变density的值,因为屏幕宽度是固定的所以通过改变density的值来使设备的dp值为同一个值。

按照上述公式:

px = density * dp;

density = dpi / 160;

改变density其实就是在改变dpi。

以上是今日头条适配的实质,用autoSize的三方库

dp的推出解决了什么问题。

1.在理想情况下:dp能保证在不同设备上尺寸相等(前提是dpi是物理dpi不是Google给的规定dpi,只有dpi是物理dpi才能保证dp在不同设备上尺寸相等),如果各大厂商都按照一个尺寸(必须一个尺寸)去生产设备,并且dpi是物理实际api(在现实中并不是物理dpi,而是Google给了一个范围规定,下面给出),很简单的就达到了适配效果,因为屏幕尺寸固定,dp的尺寸也固定。

2.dp为什么能够保证在不同设备上尺寸相等

理论:

1dp的尺寸=像素点大小*1dp的像素数 经过公式变换也就是:像素点的大小*(dp值*dpi的值/160)=1/dpi*(1dp*dpi/160)=1/160

这个公式成立的前提是dpi是真实的物理dpi

例子:

我们知道了:dpi是每英寸像素点数,px是像素点数,那我有60px的实际物理长度不就是(60/dpi)英寸嘛,1px的实际长度就是 1/dpi 英寸咯。可以得到公式:长度 L(英寸) = px /  dpi。手机的dpi不同,那1px的物理长度其实就不同。

 dip其实为了达到展示一样物理长度才弄出来的一个概念,最后还是需要转换成像素来显示的。

为了让每部手机上dip都显示一样物理长度,那只需要dip和px转换满足关系:dip = n * px /dpi (n > 0)。那么

px = dip * dpi / n。设备通过这样的对应关系来决定显示的像素值,这样显示出的像素值不同,而保证物理长度相同了。

我们来算一下看。比如20dip的长度:先计算20dip对应的px为20 * dpi /n,物理长度为 px / dpi = (20 * dpi / n) /dpi = 20/n(英寸)。n是一个固定值,那么对于所有设备来说, 20 dip都会显示成 20/n 英寸长的像素。


Android将这个n值定为160。这个值设为160,是因为第一款Android设备(HTC的T-Mobile G1)是属于160dpi。

那么,当设备dpi为160时,1px = 1dip。
 

3.什么是物理dpi,什么是Google给的dpi有什么影响

dpi的定义上面写的很清楚,算法也是给出一个例子:

我们以一个 4.95 英寸 1920 * 1080 的 nexus5 手机设备为例:

计算:物理dpi,用这个实际设备计算的物理dpi是能保证dp的长度固定的。

  1. 计算直角边像素数量: 19202+10802=2202^2(勾股定理)。
  2. 计算 DPI:2202 / 4.95 = 445。
  3. 得到这个设备的 DPI 为 445 (每英寸的距离中有 445 个像素)。

计算:dp

  • 先明白一个概念,所有显示到屏幕上的图像都是以 px 为单位。
  • Dip 是我们开发中使用的长度单位,最后他也需要转换成 px。
  • 计算这个设备上 1dip 等于多少 px:
    px = dip x dpi /160
    px = 1 x 445 / 160 = 2.78
  • 通过上面的计算可以看出在此设备上 1dip = 2.78px,那么这是一个真实的故事吗? nonono,其中的关键值 dpi 并不是我们算出来的 445 ,请往下看。

Android 系统定义的 Dpi


上面计算的 445Dpi 是在 4.95 英寸下的 1920*1080 手机,那如果是 4.75 分辨率下的呢? 4.55 分辨率下的呢?。。。。可见是很麻烦的,同一个分辨率在不同的屏幕尺寸上 Dpi 也不相同。为了省事,解决这个问题, Android 中内置了几个默认的 Dpi ,在特定的分辨率下自动调用,也可以手动在配置文件中修改。

 ldpimdpihdpixhdpixxhdpi
分辨率240x320320x480480x800720x12801080x1920
系统dpi120160240320480
基准比例0.7511.523

这是内置的 Dpi ,啥意思? 在 1920*1080 分辨率的手机上 默认就使用 480 的 dpi ,不管的你的尺寸是多大都是这样。

说到底,因为有dpi这个动态的系数,我们在使用dp的时候才能兼容不同分辨率的设备。

到这里,应该都明白了 dpi 的由来,以及系统 dpi 跟物理 dpi 并不一定相同。在系统中使用的全部都是系统 dpi,没有使用物理 dpi,也获取不到物理 dpi。物理 dpi 主要用于厂家对于手机的参数描述(也可以看做 ppi )!

 

 

引申问题dp为什么是一个物理单位又不是一个物理单位?

物理单位的定义是一个单位长度是固定的。
是物理单位:在理想的状态下大家如果都按照:Google最开始的制造标准 (使用物理dpi)去出产手机那每个dp的长度是固定的1/160确实是一个物理长度单位
不是物理单位:因为手机系统使用的的dpi并不是物理dpi,所以dp的长度不再固定所以就不能说dp是一个物理长度单位

 

参考资料:

https://www.jianshu.com/p/5678f23faed3

强烈建议看这篇文章: https://www.jianshu.com/p/cd66b7e01d4a

https://www.cnblogs.com/H-BolinBlog/p/5647548.html

今日头条屏幕适配方案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值