@coder-pig
2017-09-22T14:24:00.000000Z
字数 3920
阅读 1508
Tutorial
官方API Guides的最佳实践中对此已经有详细的描述了,可以直接看官方的:
https://developer.android.com/guide/practices/screens_support.html
对于计量单位,习惯性分为:「相对单位」与「绝对单位」,前者 根据
不同的情景表现出不同的大小,比如Android里的dp,px,sp等,而后者则是
指定了一个标准,比如mm(毫米),写死了,1mm也就那么多,无论什么情况下
都是那么多,而常用的绝对单位还有in(英寸,2.54cm),pt(磅,印刷行业
常用单位),另外 1 pt = 1 / 72 in 。
图像的最小组成单元,美工PS和写网页的时候用得比较多,直观理解就是:
以前我们小时候看的黑白电视,如果你的眼睛离屏幕很近很近,不难看到屏幕
有一个个的点,这些点有个好听的名字,叫做像素点,黑白电视点的表现
形式只有黑白,半个字节4个位(1 byte = 8 bit)代表一个像素点,可以表现
2^4种颜色;后来的彩色电视则采用2个字节(16bit,ARGB)来保存像素点,所以
可以表示2^16 = 65536种颜色。
Density-independent pixel,抽象意义上的像素,与设备的实际物理像素点无关,
可以保证在不同的像素密度的设备上显示相同的效果,Android独有的长度单位。
1dp表示在屏幕像素密度为160dpi的屏幕上,1dp = 1px;
同理,在320dpi上,1dp = 2px,对了,官网上还有条公式:
px = dp * (dpi / 160)
scale-independent pixel,字体大小专用单位,会根据系统设置的字体大小进行
缩放,推荐使用12sp以上的字体(12sp以下太小),也不推荐用奇数和小数,容易造成
精度丢失问题。
1英寸大约是2.54cm,一般我们说手机多少寸就是这个单位。
就是整个手机的尺寸,一般网上都有得查,比如我之前的手机:
当然,如果你对参数有怀疑的话可以自己用尺子量,要很精确的话可以用游标卡尺~
屏幕对角线的长度,单位是英寸
计算公式如下:
对角线的平方 = 长的平方 + 宽的平方(对角线 * 对角线 = 长 * 长 + 宽 * 宽)
比如这里就是:对角线*对角线 = 4 *4 + 3 * 3 = 25;所以对角线就为5了,也就是
屏幕尺寸为5英寸;
屏幕竖直方向与水平方向的像素个数,比如:1280*720 就说明屏幕的
竖直方向上有1280个像素点,而水平方向上有720个像素点。
dot per inch,简称屏幕密度,即每英寸有多少个像素点,屏幕密度值
越大,屏幕越清晰细致,这些参数可以从一些手机评测网站找到,比如下面
的魅族MX4 Pro:
他的屏幕密度为543ppi,也就是一英寸有543个像素点,另外这个参数我们
也可以自行计算,公式如下:
假设屏幕分辨率为:x * y,屏幕密度为s,屏幕尺寸为a * b,那么有:
x * y = s * a * b
官方文档:长度宽度用dp,字体大小用sp,但是用sp的话,会有一个
问题:当用户修改系统字体大小的时候,字体大小会跟随着变化!如果我
们用的sp来修饰字体的话,当用户把系统字体调得很大,或者很小的时候,可
能会使我们的页面UI各种丑,个人还是建议使用dp来设置字体的大小,以
规避这个问题!
public class DensityUtil {
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static int dp2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public static int px2dp(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
/**
* 将px值转换为sp值
*/
public static int px2sp(Context context, float pxValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
/**
* 将sp值转换为px值
*/
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
}
public class GetScreenParameter {
//方法一:已过时,可使用,但不建议使用
public static void getResolution1(Context mContext) {
Display mDisplay = ((Activity) mContext).getWindowManager()
.getDefaultDisplay();
int W = mDisplay.getWidth();
int H = mDisplay.getHeight();
Log.i("getResolution1", "Width = " + W + "px");
Log.i("getResolution1", "Height = " + H + "px");
}
//方法二:通过getWindowManager来获取屏幕尺寸的
public static void getResolution2(Context mContext) {
DisplayMetrics mDisplayMetrics = new DisplayMetrics();
((Activity) mContext).getWindowManager().getDefaultDisplay()
.getMetrics(mDisplayMetrics);
int W = mDisplayMetrics.widthPixels;
int H = mDisplayMetrics.heightPixels;
// 屏幕密度(0.75 / 1.0 / 1.5)
float density = mDisplayMetrics.density;
// 就是屏幕密度 * 160而已,屏幕密度DPI(120 / 160 / 240)
int densityDpi = mDisplayMetrics.densityDpi;
Log.i("getResolution2", "Width = " + W + "px");
Log.i("getResolution2", "Height = " + H + "px");
Log.i("getResolution2", "density = " + density);
Log.i("getResolution2", "densityDpi = " + densityDpi);
}
//方法三:通过getResources来获取屏幕尺寸的,大部分用这个
public static void getResolution3(Context mContext) {
DisplayMetrics mDisplayMetrics = new DisplayMetrics();
mDisplayMetrics = mContext.getResources().getDisplayMetrics();
int W = mDisplayMetrics.widthPixels;
int H = mDisplayMetrics.heightPixels;
float density = mDisplayMetrics.density;
int densityDpi = mDisplayMetrics.densityDpi;
Log.i("getResolution3", "Width = " + W + "px");
Log.i("getResolution3", "Height = " + H + "px");
Log.i("getResolution3", "density = " + density);
Log.i("getResolution3", "densityDpi = " + densityDpi);
}
}
PS:对于屏幕密度很低的小屏手机,比如240*320,计算出来的尺寸,可能为:320*427
原因是:没有设置多分辨率支持的话,Android系统会将240x320的低密度(120)尺寸
转换为中等密度160dpi对应的尺寸,如果你想获得正确的物理尺寸,需要在
AndroidManifest.xml里添加下述代码:
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:resizeable="true"
android:anyDensity="true"/>