안녕세계
[안드로이드] DpToPx & PxToPx 본문
[안드로이드] DpToPx & PxToPx
Junhong Kim 2017. 8. 10. 17:34안드로이드 개발을 하다보면 Pixel → DP로 또는 DP → PX 로 바꿔줘야할 경우가 있습니다.
Android에 dp를 px로 변환식이 필요한 이유는, JAVA에서는 dp를 이용해서 View의 크기를 바꿀 수 없기 때문입니다.
* 해상도 별로 1dp의 px 값은 아래와 같이 다르게 보입니다
ldpi(=120dpi) |
1dp = 0.75px |
0.75 density |
|
mdpi(=160dpi) |
1dp = 1.00px |
1.00 density |
Baseline |
hdpi(=240dpi) |
1dp = 1.50px |
1.50 density |
|
xdpi(=320dpi) |
1dp = 2.00px |
2.00 density |
|
xxdpi(=480dpi) |
1dp = 3.00px |
3.00 density |
|
xxxdpi(=640dpi) |
1dp = 4.00px |
4.00 density |
* DP (DIP, Density Independent Pixel)
Android에서 다양한 단말 화면 크기를 서포트하기 위해 만든 단위입니다.
자신이 만든 레이아웃이 다양한 단말에서 동일하게 보이기 위해서는 dp를 써야합니다.
안드로이드는 160dpi(mdpi)를 Baseline으로 생각하므로,
480 x 320 (160dpi) LCD => dp로 480 x 320
480 x 800 (160dpi) LCD => dp로 480 x 800
480 x 800 (240dp) LCD => dp로 320 x 533 (= 480 / 1.5, 800 / 1.5)
dp = px / ( hdpi / mdpi )
dp = px / (density / 160)
dp를 px로 나타낸다면
px = dp * (density / 16)
* density 구하기
단말 화면의 density를 알기 위해서는 WindowManager를 쓰면 됩니다.
DisplayMetrics outMetrics = new DisplayMetrics();
DisplayMetrics outMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
int px = dp * outMetrics.densityDpi;
outMetrics.densityDi 변수는 (density / 160) 의 결과 값이 들어 있습니다.
그러므로 px = dp * outMetrics.density 입니다.
ps. Google Developer Site에서는 반올림 처리를 합니다 (보다 정확한 px 값을 얻기 위해 필요)
int px = (dp * outMetrics.density + 0.5);
* PxToDp & DpToPx 계산 방법
px = dp * (dpi / 160)
= dp * density
dp = px / (dpi / 160)
= px / density
위에서 160은 mdpi 값 입니다. 예로 hdpi에서 1dp는 1.5 physical px와 같습니다
dp로 뷰의 크기를 지정하면 해상도(화면의 밀도)가 다르더라도 항상 동일한 크기로 표시됩니다.
XML 코드에서는 px과 dp를 선택적으로 사용할 수 있지만, JAVA 코드에서는 무조건 PX로 인식합니다.
그러므로 px을 dp로 바꿔주는 작업(px이 dp가 되는것이 아니라 px 값에 대한 dp 비율에 대한 px 값이 나오는 것) 을 한뒤
densitiy를 알맞은 수에 곱하고 다시 px로 변환 시킵니다.
* dpi와 density 구하는 방법
DisplayMetrics displayMetrics= new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int dpi = displayMetrics.densityDpi;
float density = displayMetrics.density;
* Dp To Px (1)
public int dpToPx(Context context, float dp){
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
return px;
}
* Dp To Px (2)
public float dpToPx(Context context, float dp) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, dm);
}
* Px To Dp
public float pxToDp(Context context, float px) {
// 해상도 마다 다른 density 를 반환. xxxhdpi는 density = 4
float density = context.getResources().getDisplayMetrics().density;
if (density == 1.0) // mpdi (160dpi) -- xxxhdpi (density = 4)기준으로 density 값을 재설정 한다
density *= 4.0;
else if (density == 1.5) // hdpi (240dpi)
density *= (8 / 3);
else if (density == 2.0) // xhdpi (320dpi)
density *= 2.0;
return px / density; // dp 값 반환
}
※ 참고
[1] http://blog.naver.com/dd00oo/20200626376
[2] http://stackoverflow.com/questions/4605527/converting-pixels-to-dp
[3] http://hashcode.co.kr/questions/44/px-dp-dip-sp%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90%EC%9D%B4-%EB%AD%94%EA%B0%80%EC%9A%94
[4] http://gyuha.tistory.com/438
'Client > Android' 카테고리의 다른 글
[안드로이드] 데이터 바인딩 (0) | 2017.09.13 |
---|---|
[ 안드로이드] Google maps v2 (0) | 2017.08.11 |
[안드로이드] Color Alpha Value (0) | 2017.08.09 |
[안드로이드] RecyclerView - 아이템 강조 (Highlight) (0) | 2017.08.08 |
[안드로이드] 다른 Activity Method 호출 (0) | 2017.08.07 |