Android中你可能忽略的知识点(1)-分辨率那些事

一、dp/dip、px、sp、dpi基本概念

  • dp/dip(device independent pixels) 设备独立像素 与设备有关系 对角线每英寸的像素点的个数
  • px 像素,pixel的缩写。这个应该不需要过多解释,平常我们所说的手机的分辨率为1920x1080,这里的单位用的就是px,也就是说高为1920个像素,宽为1080个像素
  • sp 在Android中用来表示字体大小,“Android sp单位除了受屏幕密度影响外,还受到用户的字体大小影响,通常情况下,建议使用sp来跟随用户字体大小设置。除非一些特殊的情况,不想跟随系统字体变化的,可以使用dp
  • dpi 是dot per inch,每英寸多少点,ppi是 Pixel per inch,每英寸像素数,针对显示器的设计时,dpi=ppi

二、ldpi、mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi

在Android开发中我们经常看到资源文件下面有这样六个文件夹,很多人其实并不是真正的了解它们的意思,为什么会有这6个文件夹?相信大部分人也就知道是为了屏幕适配,大一点分辨率的图片放到大的文件夹里,具体的说一下,首先看一下:

image

当然还有xxxhdpi 它的分辨率为2160x3840,也就是常说的4K屏,目前市场上好像只有一款索尼Xperia Z5 Premium。

其实这六个密度的图片文件夹与之对应的是AndroidDisplayMetrics类中的6个常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* Standard quantized DPI for low-density screens.
*/
public static final int DENSITY_LOW = 120;

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

/**
* Standard quantized DPI for high-density screens.
*/
public static final int DENSITY_HIGH = 240;

/**
* Standard quantized DPI for extra-high-density screens.
*/
public static final int DENSITY_XHIGH = 320;

/**
* Standard quantized DPI for extra-extra-high-density screens.
*/
public static final int DENSITY_XXHIGH = 480;

/**
* Standard quantized DPI for extra-extra-extra-high-density screens. Applications
* should not generally worry about this density; relying on XHIGH graphics
* being scaled up to it should be sufficient for almost all cases. A typical
* use of this density would be 4K television screens -- 3840x2160, which
* is 2x a traditional HD 1920x1080 screen which runs at DENSITY_XHIGH.
*/
public static final int DENSITY_XXXHIGH = 640;

那么这些常量具体是用来做些什么的呢?
我们可以看到注释:也就是说当手机dpi是120的时候会加载ldpi下的资源,160的时候会加载mhdpi下的资源,以此类推…但是我们在开发中可能并不会真的要建立这6个资源文件夹,因为这6套资源图片文件所占的容量大小还是不可小觑的,毕竟xxxhdpi中的每张图片都不是很小的。

那么我们在和UI小姐姐要图的时候该怎么要呢?相信目前很多开发人员都会用IOS中的@2X的图片,为什么可以直接用IOS的@2X图片呢?先来看一下IOS中手机尺寸和分辨率

设备 屏幕尺寸 分辨率 Reader
iPhone4/4s 3.5 640x960 @2x
iPhone5/5s/5c 4.0 640x1136 @2x
iPhone6 4.7 750x1334 @2x
iPhone6P 5.5 1242x2208 @3x
iPhone7 4.7 750x1334 @2x
iPhone7P 5.5 1242x2208 @3x
iPhone8 4.7 750x1334 @2x
iPhone8P 5.5 1080x1920 #3x

我们可以看到上面@2x的图的分辨率都是750x1334,而我们的xhdpi的分辨率为720x1280,相差的不多,所以一般的公司只按照IOS的UI设计一套UI图和切图,而苦逼的Android开发就硬着眉头上吧。当然如果是一些小的icon的在屏幕适配的时候不适合的话,可以放到mdpi文件夹中,这个具体细节就得自己去试了。

当然我个人觉得Android有自己的风格,比如Android中的Material Design风格,以及Android中的View,progressbar等等,如果非要为了统一那么开发人员必定会付出额外的时间去开发UI设计的效果,这样反倒浪费了时间同时也不能展现出来各个平台的独有的特性,GoogleIO刚刚结束,Google出品的APP将Android平台的特性展现的淋漓尽致,当然这些都纯属个人看法,话说回来,那么就需要UI设计师了解Android和IOS的特性,同时为两个平台设计各个风格的UI,所以…各自安好

三、转换关系

Android开发中我们在XML文件里面设置高宽度的时候都会进行一次转换,也就是把非标准尺寸转换为标准尺寸:

  • dp->px: TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, context.getResources().getDisplayMetrics());

  • in->px: TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_IN, 20, context.getResources().getDisplayMetrics());

  • mm->px: TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 20, context.getResources().getDisplayMetrics());

  • pt->px: TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PT, 20, context.getResources().getDisplayMetrics());

  • sp->px: TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, context.getResources().getDisplayMetrics());

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static float applyDimension(int unit, float value,  
DisplayMetrics metrics)
{
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}

可以看一下源码,和我们经常使用的px2dp、sp2px的方法是不是一样的,原理都是通过获取手机的DisplayMetrics,然后进行倍数转换。

四、其他

1.Manifest

在Manifest中添加子元素
android:anyDensity=”true”时,应用程序安装在不同密度的终端上时,程序会分别加载xxhdpi、xhdpi、hdpi、mdpi、ldpi文件夹中的资源。

2. .9图片

使用图片资源时,如果出现拉伸,因为图片处理的原因,会变形,导致界面走形。9-patch PNG图片也是一种标准的PGN图片,在原生PNG图片四周空出一个像素间隔,用来标识PNG图片中哪些部分可以拉伸、哪些不可以拉伸、背景上的边框位置等。

“上、左”定义可拉伸区域

“右、下”定义显示区域,如果用到完整填充的背景图,建议不要通过android:padding来设置边距,而是通过9-patch方式来定义。

Android SDK中提供了编辑9-Patch图片的工具,在tools目录下draw9patch.bat,能够立刻看到编辑后的拉伸效果,也可以直接用其他图片编辑工具编辑,但是看不到效果。

相关推荐

Android开发:最全面、最易懂的Android屏幕适配解决方案

Android屏幕适配全攻略(最权威的官方适配指导

-------------本文结束感谢您的阅读-------------