`
ydbc
  • 浏览: 718483 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

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()

  1. publicvoidsetToDefaults(){
  2. widthPixels=0;
  3. heightPixels=0;
  4. density=DENSITY_DEVICE/(float)DENSITY_DEFAULT;
  5. densityDpi=DENSITY_DEVICE;
  6. scaledDensity=density;
  7. xdpi=DENSITY_DEVICE;
  8. ydpi=DENSITY_DEVICE;
  9. noncompatWidthPixels=0;
  10. noncompatHeightPixels=0;
  11. }


其中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是个近似值,并不严格按着真实屏幕尺寸计算。

如果想在不同型号手机对同一个应用做适配,如果你在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()

  1. publicvoidsetToDefaults(){
  2. widthPixels=0;
  3. heightPixels=0;
  4. density=DENSITY_DEVICE/(float)DENSITY_DEFAULT;
  5. densityDpi=DENSITY_DEVICE;
  6. scaledDensity=density;
  7. xdpi=DENSITY_DEVICE;
  8. ydpi=DENSITY_DEVICE;
  9. noncompatWidthPixels=0;
  10. noncompatHeightPixels=0;
  11. }


其中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是个近似值,并不严格按着真实屏幕尺寸计算。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics