当前位置:操作系统 > 安卓/Android >>

android 项目移植/分辨率适配与dip(dp)的使用

如果想在不同型号手机对同一个应用做适配,如果你在xml中全部使用dp没有使用px,那么适配上依然很有可能出问题!
无数人存在误区,认为自己使用的都是dp,为什么在手机A上面和手机B上面看上去比例不一样,为什么在A手机上显示正好而手机B上却显示到屏幕外面
每次解释的都很累,所以写此blog

首先先明确几个概念
density值表示每英寸有多少个显示点(*)
dip/dp: device independent pixels(设备独立像素)
注意:dip与屏幕密度有关,屏幕密度与硬件有关,硬件设置不正确,有可能导致dip不能正常显示。在屏幕密度为160的显示屏上,1dip=1px
下面是一些分辨率信息
名称  分辨率  屏幕密度
QVGA  320*240  120
WQVGA400  400*240  120
WQVGA432  432*240  120
HVGA  640*480  160
WSVGA  1024*600  160
WXGA800  1280*800  160
WVGA800  800*480  240
WVGA854  854*480  240
WXGA720  1280*720  320

下面没有特殊说明的话,屏幕的宽度都指其像素数
我们在手机A上面放了一张图片,120px宽,手机屏幕240px宽,也就是说图片的宽度占了整个屏幕的一半
如果把应用安装在手机B上,B的宽度=320px,那么我们希望图片宽度为多少呢?如果大家希望按着比例缩放,那图片宽度应该是160px,占屏幕宽度的50%

如果我们在xml中使用的单位为dp,下面看看如何保持这个比例:
px = (density/160)dp(density这里是(*)的意思)
我们把所期待的比例记为rate,baseDensity=160,屏幕的宽度(像素数)为x,屏幕密度为density
那么rate=((density/baseDensity)*dp)/x;
这里baseDensity是已知的=160,dp也是已知的,因为是你写的嘛。
未知的是density屏幕密度和屏幕宽度x

rate可以写为:
rate=(dp/baseDensity)*(density/x);
现在情况就比较明朗了,rate=K(常数)*(density/x);
如果想保持rate不变,那么需要保证density/x保持比例

给数学不好的同学多解释两句
想保持rate的话,必须要手机A的屏幕密度/屏幕宽度=手机B的屏幕密度/屏幕宽度
或者说手机A的屏幕密度/手机B的屏幕密度=手机A的屏幕宽度/手机B的屏幕宽度

同样,如果你要保持纵向也保持等比缩放,那么也同样需要保持比例。
只有这样,你的应用才能看上去是等比缩放的。
使用dp保持比例只和这些有关,和你屏幕大小半点关系都没有。

还有另一种方式来保持比例:就是直接使用比例方式定义组件大小
但是很有局限性,只有LinearLayout中可以使用android:layout_weight属性

其实很容易理解,给大家举个例子
很多人觉得,如果项目中全部使用dp,那么就可以完美移植。
我们的一个移植项目,任务是把应用从A(分辨率为WXGA720=1280*720)移植到B(分辨率WVGA800=800*480)
其中A的密度=320,B的密度为240

我们现在来看看A横向有多少个dp
A dp数=720/(320/160)=360
B dp数=480/(240/160)=320

手机A横向有360个dp,如果你的图片占用360个dp,B去哪找你多出来的40dp呢!必然它会显示在屏幕外面阿!

ps:下面是一点相关内容
下面是函数void android.util.DisplayMetrics.setToDefaults()
[java] 
public void setToDefaults() { 
    widthPixels = 0; 
    heightPixels = 0; 
    density = DENSITY_DEVICE / (float) DENSITY_DEFAULT; 
    densityDpi = DENSITY_DEVICE; 
    scaledDensity = density; 
    xdpi = DENSITY_DEVICE; 
    ydpi = DENSITY_DEVICE; 
    noncompatWidthPixels = 0; 
    noncompatHeightPixels = 0; 

其中density变量注释如下
density变量注释 写道
float android.util.DisplayMetrics.density

The logical density of the display.
This is a scaling factor for the Density Independent Pixel unit, where one DIP is one pixel on an approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), providing the baseline of the system's display.
Thus on a 160dpi screen this density value will be 1; on a 120 dpi screen it would be .75; etc.

This value does not exactly follow the real screen size (as given by xdpi and ydpi, but rather is used to scale the size of the overall UI in steps based on gross changes in the display dpi.
For example, a 240x320 screen will have a density of 1 even if its width is 1.8", 1.3", etc.
However, if the screen resolution is increased to 320x480 but the screen size remained 1.5"x2" then the density would be increased (probably to 1.5).

See Also:
DENSITY_DEFAULT
可以看出这个density是个近似值,并不严格按着真实屏幕尺寸计算。


作者:su1216
补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,