android 如何在DP、PX、SP之间相互转换,尤其是DP和SP?

6xfqseft  于 2023-03-11  发布在  Android
关注(0)|答案(7)|浏览(140)

我已经知道DPSPPX的区别了,但是搜索这个主题后,我发现没有一个完全让我满意的,也许这个帖子是重复的,但是我还是想知道DPPXDPSPSPPXPXSP的转换公式是什么,从SPDP,从DPSP?我知道一些代码可以做到这一点,但它们并不完美。

dnph8jn4

dnph8jn41#

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

xhv8bpkk2#

公认的答案缺少一些有用的转换。

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,它在低密度电话上看起来大而在高密度电话上看起来小。)密度以每英寸点数来测量公式是px = dp * density。所以你只要乘以或除以密度就可以在pxdp之间转换。
  • sp表示与缩放无关的像素。它仅用于字体,而不用于视图。它与dp类似,只是它也考虑用户首选项。考虑用户首选项的这种密度称为缩放密度。例如,将TextView字体设置为30 sp大小,将使文本在所有设备上看起来都是相同的物理大小。但是,您的祖母可能会在她的手机设置中将她首选的字体大小一直调高到最大,所以30 sp文本在她的手机上看起来会比你的大。公式是px = sp * scaledDensity
  • DP和SP的含义
  • DP到SP的转换通常没有用
8fsztsew

8fsztsew3#

要将维度转换为整数或像素,您需要使用“***getDimensionPixelSize(R.dimen.your_dp_value)***”函数,如...
在dimens.xml中设置值

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

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

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

pcww981p4#

对于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)

bgtovc5b

bgtovc5b5#

你可以写一个不需要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);
}

以此类推,其他量也可以换算。

gxwragnw

gxwragnw6#

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

yshpjwxd7#

只要反转applyDimension()就可以了,所以这个解决方案应该对所有单元都有效。

public static int unApplyDimension(int unit,float value){
    return (int)( b.getTextSize()/TypedValue.applyDimension(
        b.getTextSizeUnit(),1,
        getApplicationContext().getResources().getDisplayMetrics()));
}

我知道我的格式很糟糕。也许不应该把它做成一行。哦好吧。
Tested &正在工作,但是在一个稍微不同的上下文中,我必须动画按钮的文本大小,其中初始文本大小单位可以是任何东西。

相关问题