如何将DP,PX,SP相互转换,尤其是DP和SP?

时间:2015-04-16 03:47:08

标签: android pixel density-independent-pixel

我知道 DP SP PX 之间存在差异。在搜索了这个主题后,我发现没有什么能让我完全满意。也许这篇文章是重复的,但我仍然想知道从 DP 转换为 PX DP 转换为 SP ,从 SP PX ,从 PX SP ,从 SP DP ,从 DP SP ?我知道一些代码可以做到这一点,但它们并不完美。

6 个答案:

答案 0 :(得分:115)

DP到PX:

public static int dpToPx(float dp, Context context) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
}

SP到PX:

public static int spToPx(float sp, Context context) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, context.getResources().getDisplayMetrics());
}

DP到SP:

public static int dpToSp(float dp, Context context) {
    return (int) (dpToPx(dp, context) / context.getResources().getDisplayMetrics().scaledDensity);
}

答案 1 :(得分:44)

接受的答案缺少一些有用的转换。

SP到PX

float sp = 20;
float px = sp * getResources().getDisplayMetrics().scaledDensity;

float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());

PX到SP

float px = 70;
float sp = px / getResources().getDisplayMetrics().scaledDensity;

DP到PX

float dp = 20;
float px = dp * getResources().getDisplayMetrics().density;

float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());

PX到DP

float px = 70;
float dp = px / getResources().getDisplayMetrics().density;

备注

  • 我在上面选择的花车(2070)是任意值。如果您愿意,可以插入不同的号码。
  • px指的是像素。设备每英寸屏幕空间的像素数称为密度。
  • dp表示与密度无关的像素。也就是说,无论使用什么设备,实际尺寸应该相同。例如,如果我将视图设置为100 dp宽,则在新的高密度手机上的宽度与在旧的低密度手机上的宽度相同。 (如果我将宽度设置为100 px,另一方面,它在低密度手机上看起来很大而在高密度手机上看起来很小。)密度以每英寸点数(DPI)来衡量。公式为px = dp * density。因此,您只需乘以或除以密度即可在pxdp之间进行转换。
  • sp表示与比例无关的像素。它仅用于字体,而不是视图。它类似于dp,但它也会影响用户首选项。考虑用户偏好的密度称为缩放密度。例如,将TextView字体设置为30 sp的大小将使文本在所有设备上看起来通常看起来具有相同的物理尺寸。但是,您的祖母可能会在她的手机设置中最大限度地使用她的首选字体大小,因此30 sp文本在她的手机上会比在您的手机上看起来更大。公式为px = sp * scaledDensity
  • Meaning of DP and SP
  • DP到SP转换通常不太有用

答案 2 :(得分:4)

要将Dimension转换为Integer或Pixel,您需要使用" getDimensionPixelSize(R.dimen.your_dp_value) "功能,就像......

在dimens.xml中创建一个值

<dimen name="padding_10">10dp</dimen>

现在可以使用像素或整数中的那个值,如下所示:

int sizeInPixel = context.getResources().getDimensionPixelSize(R.dimen.padding_10);

答案 3 :(得分:1)

对于kotlin我创建了一个扩展函数:

fun Number.spToPx(context: Context) = TypedValue.applyDimension(
    TypedValue.COMPLEX_UNIT_SP, this.toFloat(), context.resources.displayMetrics).toInt()

您可以像16.spToPx(context)16.5.spToPx(context)

一样使用它

(我将这些功能放在KotlinExtensions.kt文件中)

答案 4 :(得分:0)

您可以编写不需要contextresources的方法:

public static int dpToPx(int dp) {
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

public static int spToPx(int sp) {
    return (int) (sp * Resources.getSystem().getDisplayMetrics().scaledDensity);
}

类推,其他数量也可以转换。

答案 5 :(得分:0)

根据 TypedValue#applyDimension 源代码并利用 Kotlin 扩展:

val Float.toSp get() = this * Resources.getSystem().displayMetrics.scaledDensity

来自 link 的其他扩展

val Float.toPx get() = this * Resources.getSystem().displayMetrics.density

val Float.toDp get() = this / Resources.getSystem().displayMetrics.density