본문 바로가기
Android

[깡샘의 안드로이드 프로그래밍] 정리 15 - 논리적인 크기 획득

by 들풀민들레 2018. 1. 5.

 

본 글은 [깡샘의 안드로이드 프로그래밍 - 루비페이퍼] 의 내용을 발췌한 것입니다.
좀더 자세한 내용은 책을 통해 확인해 주세요.

 

 

 

 

 

 

13장. 커스텀뷰 개발

 

13.2.3. 코드에서 논리적인 크기 획득

 

화면을 구성하면서 뷰나 문자열의 크기를 지정할 때 물리적인 단위를 사용하지 않고, 논리적인 단위를 사용하는 것만으로 다양한 스마트폰 크기에 호환성을 확보할 수 있습니다. 

하지만 자바 코드에서 개발자가 직접 크기를 명시할 때는 논리적인 단위를 사용할 수 없으며, 오직 픽셀 단위로만 적용됩니다.

자바 코드로 크기를 명시해야 하는 대표적인 예가 커스텀 뷰입니다. 원의 반경, 문자열 크기, 선의 두께 등 커스텀 뷰에서는 다양한 크기를 명시해야 하는데요. 픽셀 단위로만 지정할 수 있으며, 이 때문에 스마트폰 크기 호환성에 문제가 될 수 있습니다.

 

무슨 문제가 된다는 걸까요? 간단한 예로 자바 코드에서의 크기 지정에 문제점을 살펴보겠습니다.

다음은 간단하게 화면에 사각형을 그리는 코드입니다.

 

Paint paint=new Paint();

paint.setColor(Color.RED);

paint.setStyle(Paint.Style.STROKE);

paint.setStrokeWidth(30);

Rect rect=new Rect(10, 10, 540, 300);

canvas.drawRect(rect,paint);

 

위의 코드에서 중요한 부분은 크기 지정 부분입니다. 선 두께를 30으로 지정하였고 사각형의 가로 크기도 좌표로 주었지만, 530 정도의 크기를 가지고 있습니다. 이를 크기가 다른 각각의 스마트폰에서 실행해 보겠습니다.

 

 

 

두 스마튼폰의 가로 크기는 각각 왼쪽 폰이 1080픽셀이며 오른쪽 폰이 720픽셀입니다. 

모두 사각형이 잘 그려지기는 했습니다. 하지만 사용자 관점에서 느끼는 차이는 큽니다. 

왼쪽은 화면에서 가로 방향 절반 정도의 크기로 나온 거로 느껴지고, 오른쪽은 가로 방향 대부분을 차지한 것처럼 느껴집니다. 

같은 코드로 적용하였지만 오른쪽 폰이 너무 크게 나와 버렸습니다. 만약 크기를 더 크게 지정하여 사각형을 그렸다면 오른쪽 폰에서는 사각형이 화면을 벗어나서 그려졌을 겁니다.

 

자바 코드에서는 크기 값을 픽셀 단위로만 지정해야 해서 나타나는 문제입니다. 

이 문제를 고려해서 커스텀 뷰를 개발할 때 크기 지정에 신경을 써 주어야 합니다. 이 문제를 해결하려면 두 가지 방법을 생각할 수 있는데요. 첫 번째 방법은 7장에서 살펴보았던 DisplayMetrics 객체를 이용해서 스마트폰의 크기 정보를 획득한 다음, 자바 코드에서 스마트폰 크기 호환성을 고려한 크기 계산을 직접 하는 방법입니다.

 

DisplayMetrics dm=getResources().getDisplayMetrics();

float strokeWidth=15*dm.density;

int rectWidth=(int)(150*dm.density);

int rectHeight=(int)(150*dm.density);

int position=(int)(10*dm.density);

Paint paint=new Paint();

paint.setColor(Color.RED);

paint.setStyle(Paint.Style.STROKE);

paint.setStrokeWidth(strokeWidth);

Rect rect=new Rect(position, position, rectWidth, rectHeight);

canvas.drawRect(rect,paint);

 

DisplayMetrics 객체를 이용해 모든 크기와 위치를 동적으로 계산해서 적용한 예입니다. 위의 코드로 테스트하면 다음의 결과를 얻을 수 있습니다.

 

 

이처럼 DisplayMetrics를 이용하여 자바 코드에서 직접 계산하여 크기를 명시할 수 있습니다.

두 번째는 자바 코드를 길고 복잡하게 만들 때 이용하는데요. 크기를 리소스로 등록하여 이용하는 방법입니다. 우선 values/dimens.xml 파일에 사용하고자 하는 크기를 논리 단위를 이용하여 등록해 줍니다.

 

<dimen name="strokeWidth">15dp</dimen>

<dimen name="size">150dp</dimen>

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

 

그리고 코드에서 이 리스소를 획득하면 알아서 각 스마트폰의 해상도에 맞게 계산된 픽셀값이 반환됩니다.

 

int size = context.getResources().getDimensionPixelSize(R.dimen.size);

int strokeWidth= context.getResources().getDimensionPixelSize(R.dimen.strokeWidth);

int position= context.getResources().getDimensionPixelSize(R.dimen.position);