【问题标题】:How to convert DP, PX, SP among each other, especially DP and SP?DP、PX、SP如何相互转换,尤其是DP和SP?
【发布时间】:2015-06-22 06:51:12
【问题描述】:

我知道DPSPPX之间的区别。在搜索了这个主题之后,我发现没有什么能让我完全满意。可能这个帖子是重复的,但是我还是想知道DPPXDPSP,从 SPPX,从 PXSP,从 SP DP,从 DPSP?我知道一些代码可以做到这一点,但它们并不完美。

【问题讨论】:

标签: android pixel density-independent-pixel


【解决方案1】:

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);
}

【讨论】:

  • @DerGolem 我希望我能找到一个可靠的例子来说明它们何时可以相同和不同,但我觉得这是一个灰色地带。很多人(包括我)都知道什么是dp和sp,以及它们之间的假设差异,但一些实际方面仍然一无所知。
  • @Android777。嗯,他们是mostly 一样。根据经验,始终使用dp 表示视图,使用sp 表示字体。你永远不会失败。真诚地,我从来没有进一步调查,因为我关注了这个golden rule
  • @DerGolem 我完全同意,但是我们遇到了一个关于 dp 和 sp 之间转换的问题,我们不确定这是否值得考虑......
  • @AndroidEx 你是对的。根据用户对文本大小的偏好,SP 可以不同于 DP。从 sp 到 px 或 dp 的转换是必要的,例如在自定义绘图中,您希望图形的大小以某种方式与画布上绘制的文本相对应。
  • sp 一错一错 public static int convertDpToSp(float dp, Context context) { return (int) (convertDpToPixels(dp, context) / context.getResources().getDisplayMetrics().scaledDensity ); }
【解决方案2】:

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

在dimens.xml中创建一个值

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

现在对于像素或整数值,您可以使用如下:

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

【讨论】:

  • 最干净的解决方案恕我直言,没有提到将文件拆分为值-* 如果需要,您可以获得不同密度的不同值...
【解决方案3】:

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

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 的转换通常没有用

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      您可以编写一个不需要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() 未针对当前屏幕进行配置,无法根据文档使用尺寸单位
      【解决方案6】:

      根据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
      

      【讨论】:

        猜你喜欢
        • 2014-08-21
        • 1970-01-01
        • 2011-01-02
        • 1970-01-01
        • 1970-01-01
        • 2014-10-09
        • 2012-01-08
        • 2017-04-10
        • 1970-01-01
        相关资源
        最近更新 更多