SilentKnight
SilentKnight

Reputation: 14011

How to convert DP, PX, SP among each other, especially DP and SP?

I have known the difference among DP, SP and PX. And after searching this topic, I found nothing satisfying me completely. Maybe this post is a duplicate, but I still want to know what is the formula of converting from DP to PX, and DP to SP, from SP to PX, from PX to SP, from SP to DP, from DP to SP? I have known some codes to do this, but they are imperfect.

Upvotes: 112

Views: 101848

Answers (7)

Riedler
Riedler

Reputation: 371

just inverting applyDimension() works for me, so this solution should work for all units.

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

my formatting is atrocious, I know. Probably shouldn't have made it a oneliner. Oh well.

Tested & is working, but in a slightly different context where I had to animate the text size of a button, where the initial text size unit could be anything.

Upvotes: 0

beigirad
beigirad

Reputation: 5714

According to TypedValue#applyDimension source code and take advantage of Kotlin extension:

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

Other extensions from link

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

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

Upvotes: 2

Nicholas Oli
Nicholas Oli

Reputation: 131

You can write a method, that doesn't need context or resources:

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

By analogy, other quantities can be converted.

Upvotes: 2

Vedant Agarwala
Vedant Agarwala

Reputation: 18819

For kotlin I created an extension function:

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

You can use it like 16.spToPx(context) or 16.5.spToPx(context)

(I place such functions in a KotlinExtensions.kt file)

Upvotes: 6

AndroidEx
AndroidEx

Reputation: 15824

DP to PX:

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

SP to PX:

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

DP to SP:

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

Upvotes: 236

Suragch
Suragch

Reputation: 511538

The accepted answer is missing a few useful conversions.

SP to PX

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

or

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

PX to SP

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

DP to PX

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

or

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

PX to DP

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

Notes

  • The floats I chose above (20 and 70) were arbitrary values. You can plug in different numbers if you like.
  • px refers to pixels. The number of pixels that a device has per inch of screen space is called the density.
  • dp means density-independent pixels. That is, no matter what device is used, the actual size should be the same. For example, if I set a view to be 100 dp wide, it will have the same width on a new high density phone as it does on an old low density phone. (If I had set the width to 100 px, on the other hand, it would appear large on a low density phone and small on a high density phone.) Density is measured in dots per inch (DPI). The formula is px = dp * density. So you just multiply or divide by the density to convert between px and dp.
  • sp means scale-independant pixels. It is just used for fonts, not views. It is similar to dp except it also factors in the user preferences. This density with user preferences taken into account is known as scaled density. Setting a TextView font to a size of 30 sp, for example, will make the text generally appear to be the same physical size on all devices. However, your grandmother may have her preferred font size maxed all the way up in her phone settings, so 30 sp text will look bigger on her phone than it does on yours. The formula is px = sp * scaledDensity.
  • Meaning of DP and SP
  • DP to SP conversion is not generally useful

Upvotes: 107

varotariya vajsi
varotariya vajsi

Reputation: 4041

For converting Dimension to Integer or Pixel you need to use "getDimensionPixelSize(R.dimen.your_dp_value)" function, Like...

Make a value in dimens.xml

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

Now for That value in pixel or integer you can use as like below:

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

Upvotes: 10

Related Questions