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


73

我知道DPSPPX之间的区别。搜索此主题后,我发现没有什么令我完全满意。也许这个职位是一个重复的,但我还是想知道什么是从转换的公式DPPX,和DPSP,从SPPX,从PXSP,从SPDP,从DPSP?我知道一些代码可以做到这一点,但是它们并不完美。


您是否在此链接上找到了答案stackoverflow.com/questions/8309354/…–
surhidamatya


5
不,我认为没有令人满意的答案。他们是不完美的。您说这个问题已经回答了1000次,然后告诉我。
SilentKnight 2015年

Answers:


175

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
@DerGolem我希望我能找到一个可靠的示例来说明它们何时可以相同和不同,但是我觉得这是一个灰色区域。许多人(包括我在内)都知道dp和sp是什么,以及它们之间的假设差异,但是某些实际方面仍然不明确。
AndroidEx 2015年

1
@ Android777。好吧,他们是mostly一样的。根据经验,始终将dp“视图”和sp字体使用。而且你永远不会失败。真诚的,自从我遵循此原则以来,我再也没有做过任何调查golden rule
Phantômaxx

1
@DerGolem我完全同意,但是随后我们遇到了有关dp和sp之间转换的问题,我们不确定这是否是一个值得考虑的事情……
AndroidEx 2015年

1
@AndroidEx您是正确的。根据用户对文本大小的偏好,SP可以不同于DP。从sp到px或dp的转换是必需的,例如在自定义绘图中,您希望图形的大小以某种方式与画布上绘制的文本相对应。
Mitselplik '16

2
sp错误是正确的一个公共静态int convertDpToSp(float dp,Context context)}
user49557 '17

70

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

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。因此,您只需乘以或除以密度即可在px和之间进行转换dp
  • sp表示比例无关的像素。它仅用于字体,而不用于视图。它dp与之相似,不同之处在于它也影响用户的偏好。考虑到用户偏好的这种密度称为缩放密度。例如,将TextView字体的大小设置30 sp为,将使文本在所有设备上通常看起来是相同的物理尺寸。但是,您的祖母可能会在手机设置30 sp中将首选字体大小最大化,因此手机上的文字看起来会比您的手机大。公式是px = sp * scaledDensity
  • DP和SP的含义
  • DP到SP的转换通常没有用

7

要将维度转换为整数或像素,您需要使用“ getDimensionPixelSize(R.dimen.your_dp_value) ”函数,例如...

在dimens.xml中赋值

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

现在,对于该值(以像素或整数为单位),您可以如下所示使用:

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

最干净的解决方案恕我直言,无需提及将文件拆分为值-*,如果需要,您可以针对不同的密度获得不同的值...
Shockwaver '18

感谢@Shockwaver
varotariya vajsi '18年

6

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文件中)


1

您可以编写不需要的方法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);
}

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


Resources.getSystem() 未为当前屏幕配置,并且根据文档无法使用尺寸单位
T-Gott
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.