设为首页收藏本站

数字电视开发论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

快捷登录

胜天工科技销售各种数字电视信号调制卡胜天工科技销售各种数字电视信号码流卡

【游客、新手、注册会员的区别】 【积分策略和会员晋级说明】 【发帖和附件上传规则】 【如何下载感兴趣的资料】 【如何获取梦游币】 【侵权资料处理及免责说明】
查看: 693|回复: 0

Android 布局中位置和大小单位相关探索

[复制链接]
  • TA的每日心情
    开心
    3 天前
  • 签到天数: 2059 天

    [LV.Master]伴坛终老

    新浪微博达人勋

    发表于 2014-12-7 22:28:16 | 显示全部楼层 |阅读模式
    分享到:
    消息来自- 北京
    在Android Layout xml文件编辑中,常常需要指定View的位置,大小,间距等。 这些数值可以用多种单位来设置。例如: "120dp" ,  "60dip",  "30px" , "10mm" , "1in" , "36pt"等。

    各自涵义如下:
    dp:  (Density-independent pixel). 密度无关像素单位。
    dip: dp的另一种写法。
    px: pixel. 像素点。
    mm: millimeters .毫米。
    in: inches,英寸。
    pt:points,点(英寸的 1/72)

    (mm(毫米), in(英寸), pt(点) 并非简单的指在屏幕上的大小就是1毫米,1英寸,1点,稍后具体讲解)

    先从px(pixel)和dp(Density-independent pixel)说起。

    0. 基础知识:

    0.1: 屏幕密度(Screen density):
    在屏幕的物理单元区域内像素(pixel)的数量。通常单位为dpi(dots per inch). 低密度的屏幕比高密度的屏幕在单位面积上的像素点(pixel)要少。Android将屏幕密度分6级: low, medium, high, extra-high, extra-extra-high, and extra-extra-extra-high
    dpi(dots per inch): 每英寸长度内点的个数。160dpi: 则说明在每英寸的距离上,可以显示160个pixel.

    0.2:分辨率(Resolution):
    屏幕的物理像素点的最大数量。

    0.3: dp(Density-independent pixel)相关信息:
    Android设备会运行在各种类型的设备上,显示屏也类型多样。不同的显示屏屏幕密度也不同。如果在UI制作时,指定某个距离是N 个Pixel。则在屏幕密度不同的设备上,这个距离就会明显不同。例如:Screen A 160dpi 。Screen B 320dpi  则在Screen A上这个距离仅是Screen B上这个距离的一半。所以需要一个计量单位,与屏幕密度没有关系。所以就产生了dp(Density-independent pixel).

    dp: 一个虚拟的像素(pixel)单位,使用它定义UI Layout,则定义的尺寸和位置和屏幕密度无关。
    density-independent像素与160dpi屏幕下的像素(pixel)相同。
    在真实使用的屏幕像素密度不为160dpi时,系统会根据屏幕密度自动转换dp值到真实pixel值。转换公式为:
    px = dp * (dpi / 160)
    例如:dpi等于240的屏幕。 一个dp等于1.5个pixel.      dpi等于320的屏幕, 一个dp等于2个pixel.

    在Android Layout UI 的长度单位使用上,推荐使用dp,使得UI在屏幕密度不同的屏幕上效果相同。

    1.  编程得到分辨率和屏幕密度:
    DisplayMetrics mertric = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(mertric);
          
            Log.w("SamInfo:", String.format("Screen Size is:[%dx%d]. Screen density:[%f]. DPI:[%d]. XDPI:[%f]. YDPI:[%f]. scaledDensity:[%f]", mertric.widthPixels, mertric.heightPixels, mertric.density, mertric.densityDpi, mertric.xdpi, mertric.ydpi, mertric.scaledDensity));

    mertric.widthPixels,
    mertric.heightPixels,
    mertric.density,
    mertric.densityDpi,
    mertric.xdpi,
    mertric.ydpi,
    mertric.scaledDensity

    分别得到多种信息。

    2. 显示的实际大小探讨:
    前面提到UI中的单位包括mm(毫米), in(英寸), pt(点),这些都是绝对数据。就算px,dp,在知道一些数据如屏幕密度值后,还是可以计算出它的理论真实大小的。那么是否可以说,我们在Layout  Xml 文件中定义的距离,与实际显示中的真实大小(比如几英寸或者几毫米)完全匹配呢?

    思考以下几个问题:
    A . 长度为1in(英寸)的Button. 是否在不同尺寸,不同分辨率,不同屏幕密度的Screen上长度相同?
    B.  长度为160dp的Button。 是否在不同尺寸,不同分辨率,不同屏幕密度的Screen上长度相同?

    理论上:
    A:1in长度的Button, 在人和Screen上,不管其尺寸,分辨率,屏幕密度有何区别,都应该是1英寸长。
    B:长度为160dp的Button则稍有复杂。分析如下:
    不管屏幕尺寸,分辨率,只要屏幕密度为160dpi. 则此Button长度都应该是1in。
    不管屏幕尺寸,分辨率,屏幕谜底为Ndpi.  每个dp所占pixel应该有:(N/160)个。所以160个dp 需要(N/160)*160个pixel.  即N个Pixel。  N个pixel. 不正就是1in的长度么?

    所以从理论上来说:1in的Button。160dp的Button。在任意尺寸,任意分辨率,任意屏幕密度下,长度都是真实的1in.(事实真的如此么?很值得怀疑吧,很明显,同样的程序在手机上,和在电视机上,1in的Button大小绝对不同的)

    实际测试如下:
    测量A:小米2手机:
    使用之前的程序,得到以下数值:
    分辨率:720x1280
    屏幕密度:320dpi.  
    xdpi=345.
    ydpi=322

    我们可以先反推一下屏幕的大小,方法如下:
    720/345=2   宽度2英寸
    1280/322=4  长度4英寸

    求对边长:
    4*4+2*2=20
    20开平方=4.5
    所以得到屏幕尺寸为4.5英寸。和真实4.3英寸差不多。

    测量结果:
    在小米2上,1in和160dp的Button。 长度确实基本为1英寸。

    测量B:某Android Pad:
    使用之前的程序,得到以下数值:
    分辨率:1024x552
    屏幕密度:160dpi.  
    xdpi=160.
    ydpi=160

    我们可以先反推一下屏幕的大小,:
    1024/160=6.4   长度6.4英寸
    552/160=3.45   宽度3.45英寸

    求对边长:
    6.4*6.4+3.45*3.45=52.86
    52.86开平方=7.27
    所以得到屏幕尺寸为7.3英寸。和真实7英寸差不多。

    测量结果:
    在此Android PAD上,1in和160dp的Button。 长度确实基本为1英寸。

    测量C:Android机顶盒+21寸电视机:
    使用之前的程序,得到以下数值:
    分辨率:1280x672
    屏幕密度:160dpi.  
    xdpi=160.
    ydpi=160

    我们可以先反推一下屏幕的大小,(虽然显然不会正确):
    1280/160=8   长度8英寸
    672/160=4.2   宽度4.2英寸

    求对边长:
    64+4.2*4.2=81.64
    81开平方=9
    所以得到屏幕尺寸为9英寸。呵呵。

    测量结果:
    在此Android STB+21寸电视机上,1in和160dp的Button。 长度大于1英寸。

    测量D:Android机顶盒+40寸电视机:
    使用之前的程序,得到以下数值:
    分辨率:1280x672
    屏幕密度:160dpi.  
    xdpi=160.
    ydpi=160

    我们可以先反推一下屏幕的大小,(虽然显然不会正确):
    1280/160=8   长度8英寸
    672/160=4.2   宽度4.2英寸

    求对边长:
    64+4.2*4.2=81.64
    81开平方=9
    所以得到屏幕尺寸为9英寸。呵呵。

    测量结果:
    在此Android STB+40寸电视机上,1in和160dp的Button。 长度远大于1英寸。

    总结和思考:
    我们发现,在手机和Pad上,这个尺寸基本正确,且推算出的屏幕大小也好像能对的上。(其实Sam也还不确定这个方法是否一定正确)。 但为何Android STB上就有如此大的差异呢?

    很显然,一个Android STB不太可能基于不同的电视机屏幕来修改其分辨率和屏幕密度。在同一时刻,它只能设定一个固定值。就如同手头这个STB设定的值,认为自己的屏幕大小为9英寸。分辨率为1280x720. 那么在这么大真实的屏幕上,则我们设定的那个Button长度就应该是1in.  但真实屏幕比9英寸要大,所以会有个缩放比例。 按此说法,如果给此STB接上9英寸的电视机,则它的效果应该和PAD和手机类似。

    而PAD和手机上效果正常,其实正是因为它系统的设置和屏幕大小匹配的缘故。系统认为自己屏幕是7英寸,又配了7英寸的物理屏幕,所以现实大小真实。
    踩过的脚印
    您需要登录后才可以回帖 登录 | 注册 新浪微博登陆

    本版积分规则

    嗨!您好:
    欢迎来到数字电视开发论坛。
    我的名字叫梦梦
    很高兴能够为您服务!
    如果已经注册【立即登录】
    还没有账号请【注册】
    嗨!您好:
    欢迎来到数字电视开发论坛。
    我的名字叫梦梦
    很高兴能够为您服务!
    如果已经注册【立即登录】
    还没有账号请

    QQ|小黑屋|手机版|Archiver|数字电视开发网 ( 京ICP备16008897号-5   

    GMT+8, 2018-4-24 12:46 , Processed in 0.233280 second(s), 38 queries , Gzip On.

    Powered by Discuz! X3.1

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表