Android density与显示效果总结

1.屏幕密度是否可以修改?

2.屏幕密度与分辨率的关系?

3.px与dip之间的转换与屏幕密度的关系?

 

1.屏幕密度是否可以修改

   Android中保存屏幕密度的系统变量为:ro.sf.lcd_density,

    此变量可以在相应的mk文件中进行修改:

  PRODUCT_PROPERTY_OVERRIDES := \
    ro.sf.lcd_density=320 \

 

2.屏幕密度与分辨率的关系

先看一组分辨率与DPI(dot per inch ,每英寸像素数)的对应关系:

4:3
VGA     640*480 (Video Graphics Array)
QVGA  320*240 (Quarter VGA)
HVGA  480*320 (Half-size VGA)
SVGA  800*600 (Super VGA)

5:3
WVGA  800*480 (Wide VGA)

16:9
FWVGA 854*480 (Full Wide VGA)
HD        1920*1080 High Definition
QHD     960*540
720p    1280*720  标清
1080p  1920*1080 高清

分辨率对应DPI
"HVGA    mdpi"
"WVGA   hdpi "
"FWVGA   hdpi "
"QHD      hdpi "
"720P     xhdpi"
"1080P   xxhdpi

再看Android源码中的DPI与屏幕密度对应关系的定义:

    public static final int DENSITY_LOW = 120;

    /**
     * Standard quantized DPI for medium-density screens.
     */
    public static final int DENSITY_MEDIUM = 160;

     public static final int DENSITY_TV = 213;
    public static final int DENSITY_HIGH = 240;

      public static final int DENSITY_XHIGH = 320;

    public static final int DENSITY_XXHIGH = 480;

    public static final int DENSITY_XXXHIGH = 640;

    /**
     * The reference density used throughout the system.
     */

默认的density:

public static final int DENSITY_DEFAULT = DENSITY_MEDIUM;

    private static int getDeviceDensity() {
        // qemu.sf.lcd_density can be used to override ro.sf.lcd_density
        // when running in the emulator, allowing for dynamic configurations.
        // The reason for this is that ro.sf.lcd_density is write-once and is
        // set by the init process when it parses build.prop before anything else.
        return SystemProperties.getInt("qemu.sf.lcd_density",
                SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT));
    }

前面说到ro.sf.lcd_density可以设置,那么在FWVGA屏的时候,是否可以设置成320呢,答案是可以的,

只是在显示效果上有很大的区别,同一分辨率的屏,lcd_density设置得越大,在屏幕上显示出来的

字和图片也就越大,具体的原因看第三个问题的分析。

3.px与dip之间的转换与屏幕密度的关系

先看转换的公式:dip值 =设备密度/160* px值

为验证此等式,做了一个测试:

    <TextView
        android:id="@+id/testText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world"
        />
   <Button
       android:id="@+id/button1"
       android:layout_width="100px"
       android:layout_height="100px"
       android:text="button_1"
       android:layout_below="@id/testText"
       />
      <Button
       android:id="@+id/button2"
       android:layout_width="100dip"
       android:layout_height="100dip"
       android:text="button_2"
       android:layout_toRightOf="@id/button1"
       android:layout_alignTop="@id/button1"
       />

当density设置为:240时,效果图
Android density与显示效果总结_第1张图片

当density设置为:320时,效果图

Android density与显示效果总结_第2张图片

从效果图上可以看出,当density为240时:dip值 =1.5* px值

                                       当density为320时:dip值 =2 * px值

网上也有很多工具类,如

 /**
  * 将dip或dp值转换为px值,保证尺寸大小不变
  * 
  * @param dipValue
  * @param scale(DisplayMetrics类中属性density)
  * @return
  */
 public static int dip2px(float dipValue, float scale) {
  return (int) (dipValue * scale + 0.5f);
 }

上面的scale=getResources().getDisplayMetrics().density;

此处确实会引起很多的误解,density不是密度吗?这和上面的公式完全不对啊,

先看看源码中对此处的density的赋值:

   density =  DENSITY_DEVICE / (float) DENSITY_DEFAULT;
        densityDpi =  DENSITY_DEVICE;
        scaledDensity = density;

其中:DENSITY_DEVICE = getDeviceDensity()     //即设备密度

      DENSITY_DEFAULT = DENSITY_MEDIUM      //即为160

这样替换进去就和上面的一样了,后面加的0.5为了使变量不为零

获取设备的density的真正方法应该是:

getResources().getDisplayMetrics().densityDpi

你可能感兴趣的:(android,px,dip,density)