출처:
안드로이드의 나인패치는 다양한 단말에 최적의 UI를 구성하기 위해 가장 필수적인 항목으로 .9.png 확장자를 가진 이미지 파일로 반복되는 영역과 패딩 영역을 이미지에 정의할 수 있다. 안드로이드 UI구성시 화면의 해상도가 다양하기 때문에 화면에 맞는 최적의 이미지를 각각 가지고 있는 것 보다 나인패치 된 이미지를 사용하는 것이 훨씬 유리하다. 나인패치를 이용하게 되면 하나의 이미지를 통해 다양한 해상도에서 최적의 UI를 구성할 수 있다.
나인패치 파일은 .png이미지에 1픽셀로 된 검은색((#000000) 테두리를 통해 인식이 된다. 왼쪽과 상단부분은 늘어나는 영역을 지정하게되며 겹치는 부분이 반복적으로 늘어나게된다. 오른쪽과 하단부분은 패딩부분으로 나인패치한 부분내에 컨텐츠가 들어가는 경우 정렬되는 범위이다.
<그림 1.7.2> 나인패치 구조
나인패치된 이미지는 아무리 늘려도 강제로 늘린 것 처럼 깨져보이는 것이 아닌 원본을 유지한 상태로 늘어나게 된다.
아래처럼 나인패치된 이미지를 늘리게 되면 늘어나는 영역의 부분이 패턴식으로 반복되어 표현되기 때문에 원본의 이미지를 유지하는 것 처럼 보인다.
<그림 1.7.3> 나인패치된 이미지와 강제로 늘린이미지 비교
나인패치된 이미지에 텍스트나 이미지등의 콘텐츠가 들어가기 위한 배경으로 사용되는 경우 콘텐츠의 패딩영역을 지정 할 수 있다.
오른쪽과 하단부분의 중복된 영역이 패딩영역으로 이 부분에 콘텐츠가 들어가게된다.
<그림 1.7.4> 나인패치 패딩영역
나인패치를 이용하면 작은 이미지 리소스로 다양한 크기의 이미지를 깨짐없이 표현 할 수 있는 장점이 있다.
다양한 해상도를 가지는 안드로이드 단말에서 없어서는 안 될 좋은 시스템이다.
하지만 나인패치 영역을 반복적인 패턴으로 보여주기 때문에 패치역역의 첫 부분과 끝 부분이 같아야 자연스럽게 표현이 된다.
반복되는 패턴이 아닌 질감을 가지는 이미지일 경우 나인패치를 사용하기는 힘들다.
<그림 1.7.5> 질감을 가진 이미지의 나인패치
이미지 스케링에 대한 팁
안드로이드에서는 이미지를 자동으로 스케일링 하게 되는데, hdpi를 기준으로 나인패치를 만들었는데 xhdpi단말기에서 실행하게 되면
이미지 크기를 늘리게 된다. 이렇게 스케일링 과정 중 이미지 영역은 스케일링 되며 나인패치 영역은 스케일링이 되지 않아
설정된 나인패치 영역이 원하는 부분에 잡히지 않을 수 있다.
그림 1.7.6의 왼쪽 이미지는 스케일링 과정에 문제점이 발생된다.
상단의 늘어나는 부분의 영역과 늘어나지 않는 영역의 디자인이 명확하게 나누기 위해 나인패치 영역을 잡은 것을 볼 수 있다.
이렇게 너무 명확하게 나눠 버리는 경우 이미지가 스케일링 되면서 의도한 나인패치의 영역이 명확하게 나누기 위한 영역이 아니게 바뀌게 될 수 있다.
이와 마찬가지로 왼쪽의 늘어나는 부분을 1픽셀로 잡혀 있는데 스케일링 과정에 나인패치의 영역이 없어져 버릴 수도 있다.
그림 1.7.6의 오른쪽 이미지는 이런 스케일링의 문제점을 해결 하기 위해 상단의 늘어나는 부분은 디자인이 바뀌는 영역을 조금 피해 여유분을 주었으며
왼쪽의 늘어나는 부분의 영역을 좀 더 크게 잡아 주었다.
<그림 1.7.6> 나인패치 DPI 스케일링 팁
- 늘어나는 영역은 최소 2~4픽셀로 한다.
- 늘어나는 영역 외 충분 한 영역을 준다.
나인패치 예제
나인패치는 버튼, 입력필드, 배경등으로 다양하게 활용 할 수 있다.
버튼의 경우 다양한 크기의 가진 버튼을 하나의 나인패치로 대응이 가능하여 어떠한 기기에서도 UI를 구성할 수 있기 때문에 나인 패치는 필수이다.
또한 리스트의 아이템의 배경으로도 많이 사용되며 다양하게 응용가능하다. 좀 더 다양항 예제를 통해 어떻게 사용하며 응용할지 알아보자.
예제1. 입력필드
입력필드에서 이미지의 가로만 늘어 나고 세로부분의 이미지는 고정되어 있어야 하는 경우 다음과 같이 나인패치가 가능하다.
그림 1.7.7은 세로로 이미지는 늘어 나지 않아야 하기 때문에 이미지의 빈 영역에 나인패치를 그린 것을 볼 수 있다.
두줄의 경우에도 영역만 늘어났지 이미지가 늘어 나지 않은 것을 확인 할 수 있다. 패딩영역을 주어 텍스트가 모두 꽉 차지 않고
좌우 위아래 패딩이 적용되어 있는 것도 주의 깊게 살펴 보자.
<그림 1.7.7> 나인패치 입력필드 예제
예제2. 버튼
늘어나는 부분을 자세히 보면 하나가 아닌 여러개로 나눌 수 있다.
이렇게 나누게 되면 이미지가 늘어나게 되면 비율에 맞게 늘어 난다.
그림 1.7.8에서 보면 하단 검은색 줄이 좌우와 같은 비율로 늘어난 것을 볼 수 있다.
<그림 1.7.8> 나인패치 버튼 예제
나인패치의 숨기는 영역(Optical Bounds)
안드로이드 4.3(젤리빈) 부터 늘어나는영역, 패딩영역 이외 숨기고 싶은 영역을 지정할 수 있는 기능이 생겼다.
이 부분은 기존의 패딩영역의 위치인 왼쪽/하단 부분에 정의하여 검은색(#000000)이 아닌 빨강색(#FF0000)으로 정의한다.
<그림 1.7.9> 나인패치 숨기는 영역
이렇게 빨강색의 숨기는 영역을 정의하게 되면 이미지가 그려질때 보이지 않게 된다.
그림 1.7.10에서 보는 것과 같이 숨기는 영역을 적용 함으로 버튼의 상/하단과 위/아래 부분의 불필요한 영역이 없어졌다.
숨기는 영역은 정의한다고 바로 사용되는 것이 아니라 버튼을 감싸고 있는 레이아웃의 layoutMode의 opticalBounds값을 통해 사용 가능하다.
안드로이드 4.3부터 사용가능하며 이전 버전에서는 동작하지 않는다.
<그림 1.7.10> 나인패치 숨기는 영역 적용
나인패치는 개발자 영역이지만 UI디자인시 나인패치를 감안해서 디자인을 하기 위해 디자이너도 반드시 알아둘 필요가 있다.
디자인 편집툴을 이용해서 나인패치영역을 선택하는 것보다 안드로이드에서 기존적으로 제공하는 툴을 이용하거나
Simple Nine-patch Generator 웹사이트(http://android-ui-utils.googlecode.com/hg/asset-studio/dist/nine-patches.html) 를 이용하면
쉽게 만들 수 있다.
안드로이드 앱 개발자가 제안하는 디자인 방법론 – 3. DPI, DIP(DP) 개념
안드로이드는 다양한 해상도와 화면의 크기를 지원한다고 이전 시간에 설명을 했다.
2013/02/28 – [개발관련/Android] – 안드로이드 앱 개발자가 제안하는 디자인 방법론 – 1. 나인패치(Nine-patch) 개념
2013/03/04 – [개발관련/Android] – 안드로이드 앱 개발자가 제안하는 디자인 방법론 – 2. 나인패치(Nine-patch) 실습
이런 다양한 기기를 지원하기 위해 개발자 뿐만아니라 디자이너들까지 어려움을 격는다.
또, 제조사에서 구글의 가이드라인에 맞지 않게끔 기기를 만들기 때문에 두번 어렵다.
기존에 웹디자이너가 안드로이드 디자인으로 넘어 오면서 혼란을 초래 할 수도 있다.
예를 들면 웹은 최소사이즈를 지정하여 디자인 하는데 반해, 안드로이드 앱의 경우 모바일 특성상 모든 화면에 컨텐츠 들이 보여야 되기 때문에
어떠한 해상도에서든 꽉찬 화면을 유지해야 되기 때문이다.
아래는 현재 출시된 대표적인 기기들의 해상도이다.
이런 다양한 해상도를 완벽하게 지원한다는건 힘들고 손이 많이 가는 일이다.
어떤식으로 안드로이드가 이미지를 처리하는지에 대해 알고 디자인을 한다면 디자인의 퀄리티는 좀더 높아 지지 않을까 생각 해본다.
말로 풀어 설명하기가 참 힘든 부분이라 이해하기가 힘들 수도 있다.
하지만 어떻게 하면 좀더 쉽게 설명 할수 있을까에 대한 고민을 많이 했으니 차근차근 하나씩 설명 해보겠다.
* PX
안드로이드는 px단위를 쓰지 않고 dip단위를 사용한다.
설명에 앞서 왜 px단위를 쓰면 안되는지, 쓰면 어떤 문제가 발생 되는지 간단한 예를 통해 알아 보자.
[Test Case]
drawable-nodpi 폴더 r.png, p.png, g.png, r.png
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
디자이너가 800×480을 기준으로 화면에 정확히 120px로 된 4개의 아이콘을 넣고 싶어 한다고 치자.
800×480에 마춰서 디자인을 했으니 문제 없이 잘 보이지만, 1280×720의 해상도에서 보니 오른쪽 부분이 횡하게 비는 것을 볼 수 있다.
px단위는 화면의 전체화면 크기를 고려 하여 표시되는 상대적 단위가 아닌 전체화면 크기와는 관계 없이 지정한 수치만큼 표시되는
절대적 표시 단위이기 때문이다.
|
|
< 800 x 480 > |
< 1280 x 720 > |
위의 앱은 실제로 본인이 개발했을때 px단위를 쓴 단적인 예이다.
800×480에 기준으로 px단위를 써서 개발을 했다.
1280×720의 해상도의 경우 엉망이 되는 정말 좋은 예제이다.
또한 웹 브라우저에서 화면 크기를 작게 할때 콘텐츠 들이 짤리는것을 보면 금방 이해가 될 것이다.
하지만 우리 안드로이드는 어떤 화면크기가 와도 화면이 절때 짤려서는 안된다.
그래서 안드로이드에서 도입된 것이 dip(dp)단위 이다.
* DPI (Dots Per Inch)
1인치(2.54 센티미터)에 들어 있는 픽셀의 수(밀도)
안드로이드에서는 dpi별로 이미지, 레이아웃을 다르게 줄 수있다.
하지만 기기별 dpi가 천차만별 이기때문에 구글에서는 아래처럼 가이드를 제시해주고 있다.
Low density (120dpi) (0.75x) : ldpi
Medium density (160dpi) (baseline) : mdpi 옵티머스원
High density (240dpi) (1.5x) : hdpi : 갤럭시S, 갤럭시S2,
Extra High density (320dpi) (2.0x) : xhdpi 갤럭시S3
Extra Extra High density (480dpi) (3.0x) : xxhdpi 갤럭시S4(미정)
구글의 가이드 라인에 의해 제조사는 dpi기준을 잡아 출시 한다.
Device independent pixel
디자이너와 개발자의 혼란을 줄이기 위해 안드로이드에서는 dpi단위를 제공한다.
dpi단위는 독립적인 크기를 나타낼 수 있도록 하는 단위이다. 이론상 어떠한 해상도에서도 같은 크기를 보여 주는것이 핵심 개념이다.
표준이 되는 화면크기를 중심으로 보다 큰 화면에서는 지정된 배율로 크기를 늘려주고, 작은 화면에서는 지정된 배율로 크기를 줄여준다.
[Test Case]
drawable-hdpi 폴더 r.png, p.png, g.png, r.png |
아까전과 다르게 800×480에서의 1280×800의 해상도에서 비슷한 크기로 보인다.
다른 점이 하나 있다면 drawable-hdpi 디렉토리에 이미지를 넣었다.
drawable-hdpi 디렉토리에 넣으면 이 이미지들은 hdpi용 이미지라는 것을
안드로이드에서 인식해서 더 크거나 작은 dpi가 들어오면 이미지를 크거나 작게 스케일링 해준다.
DPI 계산법: 원본px * (변환 할 DPI / 원본px의 DPI)
ex) HDPI의 120px을 XHDPI로 변환한다. 120*(320/240) = 160px
|
DPI 이론상 눈에 보이는 실제 이미지의 크기는 둘다 같아야 되나 오차가 발생 되어 좀 더 크거나 작게 그려질 수있다.
320/240 = 1.3333333…. 이기 때문에 120 * 1.33333… = 159.9xxxx 가 나온다.
|
px단위는 최저 1px이 기준이기 때문에 159.9xxx를 표현을 못해 160px로 그린다.
그렇기 때문에 오차가 발생 하는 것이다.
나눠서 정확하게 정수형으로 떨어 진다면 오차는 발생 하지 않게 된다.
또한 해상도와 인치의 규격에 맞지 않게 기기를 만든경우에도 오차가 발생 될수 있다. (대표적으로 갤럭시탭7)
하지만 이렇게 스케일링이 된다고 믿어서는 안된다. 폰마다 가로 dpi가 모두 다르기 때문이다.
그래서 레이아웃 구성시 동적으로 구성해야 되며, 이런 동적인 구성을 하기 위한 가이드 라인을 작성 하는 법에 대해서 다음에 알아 보겠다.
'IT_Programming > Android_Java' 카테고리의 다른 글
Parcelable vs Serializable (0) | 2015.07.08 |
---|---|
[펌] Beacon(Bluetooth 4.0 Based) 프로토타이핑 - 비콘 클라이언트 아키텍처 (0) | 2015.07.07 |
Android Support Library (0) | 2015.07.01 |
View Alpha VS ARGB Color Alpha 성능 (0) | 2015.07.01 |
Android Theme VS Style (0) | 2015.07.01 |