아아니 분명히 맞게 크기를 계산해서 넣었던 것 같은데 이상하네 --> dp와 px의 단위가 달라서 생긴 문제! 이번 기회에 dp에 대해 제대로 알아보자
PX는 화면을 구성하는 최소 단위이다. 화면의 크기나 픽셀 밀도와 상관 없이 같은 크기로 보여진다. 따라서 같은 화면 크기의 두 기기여도 픽셀 밀도가 서로 다르면, 같은 PX으로 설정한 뷰의 크기가 다르게 보일 수 있다.
Dp는 그러한 단점을 보완하기 위해 안드로이드에서 만든 단위이다. 다양한 기기에서 동일하게 보여지기 위해서는 이 단위를 사용하는 것이 좋다.
아까 언급한 바와 같이 dp를 계산할 때 제일 중요한 것은 픽셀 밀도이다. 픽셀 밀도는 density라고 불리며 dpi를 통해서 계산할 수 있다( density = dpi / 160 ). 안드로이드 기기에서 아래와 같은 dpi가 흔하다고 한다.
val metrics = context.getResources().getDisplayMetrics();
Display Metrics는 디스플레이 사이즈, 폰트 스케일링, density 등의 정보를 가지고 있는 구조체이다.
metrics.density // dpi / 160
metrics.densityDpi // dpi
Float로 density값을 얻거나 dpi의 값을 얻을 수 있다.
px = ((dp * density) + 0.5f).toInt()
잠깐! 0.5f는 왜 더하는 거죠?
나도 이 부분이 궁금해서 검색해 보고 깨달음을 얻었다. float를 Int로 강제 형변환을 할 때 소수점이 떨어져나가게 된다. 이때 float에 0.5를 먼저 더하고 나서 Int로 바꾸게 되면 round함수를 사용하지 않아도 반올림을 한 것과 같은 효과를 얻게 된다고 한다.
https://dev-nomad.com/60
https://developer.android.com/reference/android/util/DisplayMetrics
https://stackoverflow.com/questions/5255184/android-and-setting-width-and-height-programmatically-in-dp-units
https://stackoverflow.com/questions/71717360/setting-imageviews-size-and-position-as-percentages-programmatically-in-constra