美文网首页AndroidAndroid资料android
[31→100]Android界面开发精要1:尺寸

[31→100]Android界面开发精要1:尺寸

作者: 沉思的Panda | 来源:发表于2016-05-26 17:05 被阅读665次

    界面依附于具体的运行设备,更准确说是一块有一块的屏幕,所以我们首先要弄清屏幕有哪些特性。


    Android设备通用型号一栏表

    这里面有2个核心概念:

    1. 屏幕的物理尺寸,也即是通常说的屏幕大小(Screen Size),用屏幕对角线长度来表示,单位是英寸("),比如图中3.7"、4.0"、3.2"等

    2. 屏幕分辨率(Resolution),表示屏幕有多精细,单位是像素(px),比如图中480*800、1280*720等。

    3. 这两个值相除,产生了一个新的概念屏幕密度(Screen Density),即单位长度像素点数,单位是 像素/英寸(dpi)。

    以小米4为例,屏幕size = 4.6英寸(2.25英寸*4英寸),1080*1920像素。
    所以,屏幕密度为 480 = 1080/2.25 = 1920/4。

    由于Android的开放性,运行它的设备大小和分辨率并不一样,如果采用px作为基础的计算单位,在不同设备上的视觉效果是不一致的。比如,同样一个300px*100px的矩形,在480*800的手机上很显眼,而在1920*1080上可能就只是一点点了。所以我们面临了界面开发的经典问题——适配

    怎么适配——使用DP

    为了方便开发人员适配,Android提出了一个新的概念独立像素单位dp(Density-independent pixel),代替原来的像素单位px。dp与屏幕密度挂钩。Android规定:

    在一个屏幕密度为160的设备上,1dp=1px。
    

    此后,随着屏幕密度的变化,dp保持等比缩放。即

    1dp = (当前设备的屏幕密度/160) px
    1px = (160/当前设备的屏幕密度)dp
    

    由dp这个概念,Android规定了一系列的标准屏幕尺寸:

    • ldpi:屏幕密度为120。
    • mdpi:屏幕密度为160。
    • hdpi:屏幕密度为240。
    • xhdpi:屏幕密度为320。
    • xxhdpi:屏幕密度为480。
    • xxxhdpi:屏幕密度为640。
    • tvdpi:屏幕密度为213。

    除了这些标准尺寸外,也可自定义其它屏幕密度,包括Google Nexus系列都采用了一些非标准尺寸,比如420dpi、560dpi。


    Android常用设备dpi列表

    在Android代码DisplayMetrics类中,也为这些常用dpi做了定义:

    public static final int DENSITY_280 = 280;
    public static final int DENSITY_360 = 360;
    public static final int DENSITY_400 = 400;
    public static final int DENSITY_420 = 420;
    public static final int DENSITY_560 = 560;
    public static final int DENSITY_DEFAULT = 160;
    public static final int DENSITY_HIGH = 240;
    public static final int DENSITY_LOW = 120;
    public static final int DENSITY_MEDIUM = 160;
    public static final int DENSITY_TV = 213;
    public static final int DENSITY_XHIGH = 320;
    public static final int DENSITY_XXHIGH = 480;
    public static final int DENSITY_XXXHIGH = 640;
    

    DP是一个好的解决方案吗?

    在实际开发,设计人员提供的视觉设计图,视觉工具从图上直接取到的像素px,直接采用dp机制,意味着开发人员需要不断地将px转成dp,这工作量大、繁琐、重复。所以对于开发人员而言,更好的机制是利用dimension机制,将dp映射为设计图的px值。如下:

        <!-- 宽度 -->
        <dimen name="width_720_1280_1">0.50dp</dimen>
        <dimen name="width_720_1280_2">1.00dp</dimen>
        <dimen name="width_720_1280_3">1.50dp</dimen>
        <dimen name="width_720_1280_4">2.00dp</dimen>
        ……
        <dimen name="width_720_1280_716">358.00dp</dimen>
        <dimen name="width_720_1280_717">358.50dp</dimen>
        <dimen name="width_720_1280_718">359.00dp</dimen>
        <dimen name="width_720_1280_719">359.50dp</dimen>
        <dimen name="width_720_1280_720">360.00dp</dimen>
        <!-- 高度 -->
        <dimen name="height_720_1280_1">0.50dp</dimen>
        <dimen name="height_720_1280_2">1.00dp</dimen>
        <dimen name="height_720_1280_3">1.50dp</dimen>
        <dimen name="height_720_1280_4">2.00dp</dimen>
        ……
        <dimen name="height_720_1280_1277">638.50dp</dimen>
        <dimen name="height_720_1280_1278">639.00dp</dimen>
        <dimen name="height_720_1280_1279">639.50dp</dimen>
        <dimen name="height_720_1280_1280">640.00dp</dimen>
        <!-- 文字 -->
        <dimen name="text_size_720_1280_1">0.50sp</dimen>
        <dimen name="text_size_720_1280_2">1.00sp</dimen>
        <dimen name="text_size_720_1280_3">1.50sp</dimen>
        <dimen name="text_size_720_1280_4">2.00sp</dimen>
        ……
        <dimen name="text_size_720_1280_87">43.50sp</dimen>
        <dimen name="text_size_720_1280_88">44.00sp</dimen>
        <dimen name="text_size_720_1280_89">44.50sp</dimen>
        <dimen name="text_size_720_1280_90">45.00sp</dimen>
    

    这样,对界面绘制人员而言,只需要将图片上的px直接写在就可以了,节省了很多重复计算的时间。

    怎么制作这样px映射表呢?

    1. 确定UI设计基于什么样的分辨率?比如640*1136(这是iPhone5的分辨率);
    2. 确定目标适配的Android尺寸?比如720*1289;
    3. 确定dimens的dpi,常用dpi如下:

    ldpi:屏幕密度为120。
    mdpi:屏幕密度为160。
    hdpi:屏幕密度为240。
    xhdpi:屏幕密度为320。
    xxhdpi:屏幕密度为480。
    xxxhdpi:屏幕密度为640。
    tvdpi:屏幕密度为213。

    1. 执行Python代码:
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import csv
    import os
    import re
    import sys
    import zipfile
    import xml.etree.ElementTree as ElementTree
    
    '''自动生成相应的dimens.xml文件'''
    if __name__ == '__main__':
        # print "srcipt:", sys.argv[0]
        # for i in range(1, len(sys.argv)):
        #     print "argv[", i , "] = ", sys.argv[i]
    
        # 原型界面提供的尺寸
        uiWidth = 640;
        uiHeight = 1136;
    
        # 目标设备尺寸,即目标机型界面
        desWidth = 720
        desHeight = 1280
    
        # 目标屏幕密度
            # ldpi:屏幕密度为120。
            # mdpi:屏幕密度为160。
            # hdpi:屏幕密度为240。
            # xhdpi:屏幕密度为320。
            # xxhdpi:屏幕密度为480。
            # xxxhdpi:屏幕密度为640。
            # tvdpi:屏幕密度为213。
        density = 320
    
        print "<!-- "
        print "\t\tUI提供宽高: %d*%d" % (uiWidth, uiHeight)
        print "\t\t适配屏幕宽高: %d*%d" % (desWidth, desHeight)
        print "\t\t适配屏幕密度: %ddpi" % (density)
        print "--> "
    
        ratio = 1.0*desWidth/uiWidth
        # 输出合理的dimens.xml文件
        for i in range(uiWidth):
            j = i + 1
            # print "<dimen name=\"ws_%d_%d_%s\">%.2fdp</dimen>" % (desWidth, desHeight, j, 1.0 * j * density)
            print "<dimen name=\"ws%s\">%.2fdp</dimen>" % (j, 1.0 * j * ratio * 160/density)
    
        for i in range(uiHeight):
            j = i + 1
            # print "<dimen name=\"hs_%d_%d_%s\">%.2fdp</dimen>" % (desWidth, desHeight, j, 1.0 * j * density)
            print "<dimen name=\"hs%s\">%.2fdp</dimen>" % (j, 1.0 * j * ratio * 160/density)
    
        for i in range(90):
            j = i + 1
            # print "<dimen name=\"ts_%d_%d_%s\">%.2fsp</dimen>" % (desWidth, desHeight, j, 1.0 * j * density)
            print "<dimen name=\"ts%s\">%.2fsp</dimen>" % (j, 1.0 * j * ratio * 160/density)
    

    Panda
    2016-05-26

    相关文章

      网友评论

      • 公民权:求源码
        沉思的Panda:@公民权 制作px映射表的脚本已经在文章里了,还要什么源码啊
      • 无极小屋:可以写个工具类,对px和dp进行转换,很方便
        沉思的Panda:@角落里的箱 我没有大规模用过,如果你对这种方法感兴趣的话,可以关注一下这个项目:https://github.com/hongyangAndroid/AndroidAutoLayout
        无极小屋:@沉思的Panda 对性能影响大不大,如果影响不大的话我觉得还是可以接受的
        沉思的Panda:@角落里的箱 用java转化是很简单,但没有必要。纯粹用px适配性就降低了,所以还是转dp好。而如果用代码在运行时将px转成dp,对性能有影响。采用xml的方式,一次投入,以后无忧。
      • 无缘公子:如果你能提供一个demo下载,我觉得会更棒
        无缘公子:@无缘公子
        沉思的Panda:@无缘公子 嗯,回头在github上写一个
      • 无缘公子:很不错
      • 夏吙:不错,收藏啦
        夏吙: @沉思的Panda 嗯嗯,明白一些,谢谢分享
        沉思的Panda:@夏吙 能用上就更好

      本文标题:[31→100]Android界面开发精要1:尺寸

      本文链接:https://www.haomeiwen.com/subject/vorxdttx.html