Android px/dp/sp scaledDensity/density 详解

本文详细介绍了Android中px、dp、sp三种尺寸单位的区别和使用场景,重点讨论了dp如何实现屏幕适配,以及sp在字体大小调整中的作用。通过理解像素密度和缩放密度,开发者可以更好地进行Android应用的界面布局设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android中的尺寸计量单位有很多,我们常用的有3种:px , dp , sp ;

一、PX

 px的全称是( pixel ), 即像素的意思;

我们常数的 480*800 、720*1280、1080*1920指的就是像素值宽高的意思;

指屏幕是由多少个象数点所组成;

在实际编程中,我们通常不使用该单位;比如,我们指定一张图片的大小是240*400px,它在480*800的手机屏幕上占的大小是一半,而在1080*1920分辨率的手机屏幕上,这张图片占有的空间连1/4都不到,这样就造成兼容性事故;

但是在某些特定情况下,使用PX会具有优势,比如设置一道分割线,原因将在下一节解释完dp后给出;

使用方法如下(这里分别是px和dp,解释在下一节):

    <View 
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_margin="10dip"
        android:background="#000000"/>
    <View 
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_margin="10dip"
        android:background="#000000"/>


获取的方法:

1)在Activity中可以通过如下方法直接获取:

int width = getResources().getDisplayMetrics().widthPixels;
	int height = getResources().getDisplayMetrics().heightPixels;

2)在非Activity的情况下,使用如下方法:

/**
	 * 获取屏幕的宽度
	 * @author WangHuan 
	 * @email hunter.v.wang@gmail.com
	 * @see http://stackoverflow.com/questions/1016896/how-to-get-screen-dimensions
	 * @param context
	 * @return 屏幕宽度
	 */
	@SuppressWarnings("deprecation")
	public static int getScreenWidth(Context context){
		WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		Display display = windowManager.getDefaultDisplay();
		if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB_MR2){
			return display.getWidth();
		}else{
			Point size = new Point();
			display.getSize(size);
			return size.x;
		}
	}
	
	/**
	 * 获取屏幕的高度
	 * @author WangHuan 
	 * @email hunter.v.wang@gmail.com
	 * @see http://stackoverflow.com/questions/1016896/how-to-get-screen-dimensions
	 * @param context
	 * @return 屏幕高度
	 */
	@SuppressWarnings("deprecation")
	public static int getScreenHeight(Context context){
		WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		Display display = windowManager.getDefaultDisplay();
		if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB_MR2){
			return display.getHeight();
		}else{
			Point size = new Point();
			display.getSize(size);
			return size.y;
		}
	}

二、DP;

首先 dp=dip,老版本的Android系统中,常用dip,现在都用dp;

dp也是一种像素,全称“Device-Independent Pixel”,叫“设备独立像素”,这个值和“像素密度”有关;

先来说说这个“像素密度”,简称是dpi,全称是( Dots pre Inch),即每一个英寸屏幕包含的像素点数,这个值和手机的物理尺寸相关联;

px像素只说明了一个屏幕包含的点数有多少,但是点的大小不是确定的,同样是480*800,可能是手掌那么大,也可能是电影院屏幕那么大;

现在引入像素密度,用每英寸包含的像素数目,来衡量屏幕的质量水准;

一部横向宽度2英寸、480像素的手机,它的横向像数密度就是 480/2 = 240dpi ;

可以看出,“设备独立像素”是一个常量;

获取像素密度的方法是:

int densityDpi = getResources().getDisplayMetrics().densityDpi;

那么这个“像素密度”是干嘛的呢?它是将像素(PX)和设备独立像素(DP)联系起来的

它们的关系是:px=densityDpi/160*dp;  

Android系统提供了直接获取densityDpi/160的方法,该值叫做密度;获取方法是:

float density = getResources().getDisplayMetrics().density;

这样就通过像素密度将 像素和尺寸联系起来,从而解决并形成一个与设备有关的单位 dp;

在实际编程中,我们通常使用该单位,因为它是程序运行的设备密切相关,能够达到屏幕适配的效果;

附:Dp和Px的转换关系:

/**
<span style="white-space:pre">	</span> * Dp 转 Pixels
<span style="white-space:pre">	</span> * @author WangHuan 
<span style="white-space:pre">	</span> * @email hunter.v.wang@gmail.com
<span style="white-space:pre">	</span> * @see http://blog.youkuaiyun.com/zuomohuaer/article/details/39522171
<span style="white-space:pre">	</span> * @param context
<span style="white-space:pre">	</span> * @param Pixels
<span style="white-space:pre">	</span> * @return
<span style="white-space:pre">	</span> */
<span style="white-space:pre">	</span>public static int dpToPixels(Context context , float dp){
<span style="white-space:pre">		</span>float density = context.getResources().getDisplayMetrics().density;
<span style="white-space:pre">		</span>return (int)Math.ceil(dp * density);
<span style="white-space:pre">	</span>}

之前说过,为什么在分割线的时候使用px;

因为,根据PX和DP的转换关系,只有当像素密度为160的时候,1Dp=1PX;不然像素密度越高,一般就是手机屏幕越好的情况,1Px>>1PX;

这样的结果就是1Dp可能很粗,而不是我们想要的1个像素高度;所以通常使用1PX;

三,SP;

SP的全称是“ScaledPixels”,即放大像素;

Android的系统,允许字体自由缩放,在整个屏幕大小不变、像素不变的情况下,字体可以进行缩放;这样,字体的大小就和之前的英寸,像素,设备独立像素,密度都没有关系了;这个 “放大像素”和另一个参数“缩放密度(scaledDensity)”有关;

在实际编程中,我们通常将字体使用sp单位,以适应不同屏幕分辨率;

scaledDensity获取方法:

float scaledDensity = getResources().getDisplayMetrics().scaledDensity;

SP和PX的转换关系是:

/**
	 * Pixels 转 SP
	 * @author WangHuan 
	 * @email hunter.v.wang@gmail.com
	 * @see http://blog.youkuaiyun.com/zuomohuaer/article/details/39522171
	 * @param context
	 * @param px
	 * @return
	 */
	public static float pixelsToSp(Context context, float px) {
	    float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
	    return px/scaledDensity;
	}
	
	/**
	 * SP 转 Pixels
	 * @author WangHuan 
	 * @email hunter.v.wang@gmail.com
	 * @see http://blog.youkuaiyun.com/zuomohuaer/article/details/39522171
	 * @param context
	 * @param Pixels
	 * @return
	 */
	public static float spToPixels(Context context, float sp) {
	    float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
	    return sp * scaledDensity;
	}

四,总结;

DP和SP都是和PX相关的, DP通过屏幕像素密度和像素关联,SP通过缩放密度和像素关联;

实际编程中PX很少使用,一般使用DP来设置距离,SP来设置字体大小;


新浪微博:@_阡陌花开

Android 讨论群:92058507







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值