[android / 안드로이드] dpToPx() , pxToDp() 구하기
이전 글에서는 px과 dp 와의 관계를 정의하고 dpi라는 개념에 대해서도 알아봤습니다.
이번 글에서는 px 과 dp 와의 관계를 통한 실제 안드로이드에서 dpToPx() , pxToDp()를 정의하도록 해보겠습니다.
이전 글에서 px = dp × density 라는 관계식이 있다고 했습니다. 이를 바탕으로 dpToPx 메서드와 pxToDp 메서드를 정의하겠습니다. (density = 내 디바이스 dpi / 160)
정의하기 앞서 예를 들기 위해서 내 디바이스는 Pixel 3 XL(560dpi) 를 사용했습니다.
1. dpToPx() 정의
private fun dpToPx(context: Context , dp : Float) {
val px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP , dp , context.resources.displayMetrics)
Log.d("px" , px.toString())
}
입력받은 dp를 px 로 바꿔서 log 를 찍도록 했습니다.
여기서 applyDimension 메서드를 살펴보겠습니다.
public static float applyDimension(@ComplexDimensionUnit int unit, float value,
DisplayMetrics metrics)
{
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
dp(dip) 를 입력 받았을 땐 return value * metrics.density 를 하게 됩니다.
즉, 위에서 정의한 px = dp * density 관계식으로 볼 때 value 는 dp , metrics.density가 결국 density가 됩니다.
정의한 코드를 수행한 결과를 알아보겠습니다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dpToPx(this , 28.571428f)
}
현재 디바이스의 dpi 는 560dpi 이므로 density = 560 ÷ 160 = 3.5 입니다.
즉, px = 28.571428 × 3.5 = 99.999998 이라는 값이나옵니다. 반올림 하면 100이 됩니다.
입력받은 dp 값에 의해서 px 로 return 됬습니다.
2. pxToDp() 정의
private fun pxToDp(context: Context, px : Float) {
var density = context.resources.displayMetrics.density
Log.d("dp" , (px/density).toString())
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
pxToDp(this , 100f)
}
dp = px / density 이므로 dp 도 log 를 찍어서 확인했습니다.
dp = 100 / 3.5 = 28.571428 이라는 값이 나오게 됩니다.
여기까지 dp 와 px 간의 관계를 통해서 안드로이드에서 dp -> px , px -> dp 로 변환하는 방법까지 알아봤습니다.
해당 관계식을 통해서 나중에 개발하실 때 유용하게 사용하실 수 있는데 예를 들어서
RoundedCorners() 와 같은 메서드에는 px 이 들어가야 합니다.
하지만 디바이스별로 해상도가 다르기 때문에 px 을 직접 넣어주면 다른 디바이스에서는 다르게 표현될 수 있습니다.
이럴 때 이제 dpToPx() 을 만들어서 내가 dp 를 넣어주면 그 디바이스에 맞게끔 px 이 반환되게끔 사용할 수 있습니다.