*둘 다 남자입니다.
안녕하세요? 요즘 너무 사이드 프로젝트 얘기만 하는 것 같아서, 최근 회사에서 작업했던 안드로이드 개발과정에 대한 이야기를 가져왔습니다.
특히, 안드로이드 협업을 처음 해보면서 느꼈던 포인트와 좋았던 방식에 대해서 공유드릴 예정이고, 원래는 DP-PX 관계에 대해서만 얘기하려고 했는데 글을 쓰다 보니 핸드오프에 대한 이야기가 되었네요..
본론에 들어가기 전에 앞서, 꼭 말씀드리고 싶은 점은 저는 이 작업을 하던 당시 Zeplin을 사용하지 않았기 때문에 직접 PX과 DP에 대해서 공부하고 대응했지만, 뒤늦게 Zeplin을 써보니 이미 있는 기능들이 꽤 있어서 닭똥 같은 눈물을 흘렸습니다.
이 글을 읽는 디자이너분들은 저와 같은 실수를 하지 않기를 바라는 마음에 Zeplin 찬양글을 남겨봅니다. 웬만하면 Zeplin 쓰세요. 돈을 쓸 만한 가치가 있습니다..
대응의 중요성
1px=1dp 대응이 안된다면, figma의 수치와 개발할 때의 수치가 달라서 개발 전에 임의로 배수만큼 변환해줘야 하는 이슈가 있음.
보통 귀찮아서 혹은 대충 개발하다 보면 분명 휴먼 에러로 누락되거나 잘못되는 케이스가 생김
쉽게 말해, 디자이너와 개발자의 사용 단위가 다르다 보니 결국 둘 중 한 명은 dpi 대응을 해야 함. 높은 확률로 디자이너가 대응해서 dpi별 시안을 그릴 확률이 높음. 그것이 매우 귀찮음
▶️ px (Pixels): 화면상의 실제 픽셀 수를 의미. 디스플레이의 해상도에 따라 픽셀 수가 달라짐.
▶️ dp (Density-independent Pixels): 안드로이드에서 사용되는 추상적인 단위로, 다양한 화면 밀도에서도 일관된 크기를 유지하기 위해 고안되었음.
▶️ dpi (Dots Per Inch): 화면의 인치당 픽셀 수를 나타내는 지표로, 화면의 픽셀 밀도를 나타냄
안드로이드에서는 dp를 사용하여 UI 요소의 크기를 지정함으로써, 다양한 화면 밀도에서도 일관된 크기를 유지할 수 있음. dp와 px 간의 관계는 다음 공식으로 정의됨.
MDPI (160 dpi): 1dp = 1px
MDPI는 160 dpi를 가지고 있기 때문에 px변환 공식에 대입하면, 1px이 1dp입니다.
XHDPI (320 dpi): 1dp = 2px
320 dpi인 XHDPI를 px변환 공식에 대입하면, 약 2px이 1dp입니다.
즉, XHDPI는 MDPI보다 픽셀 밀도가 2배 더 높기 때문에, 1dp에 MDPI보다 2배 더 픽셀이 들어갑니다. 그래서 Figma에서 가로값이 500px인 컴포넌트는 MDPI에서 500dp와 같은 크기이지만, XHDPI에서는 250dp와 같은 크기가 돼요.
저희 회사처럼 특정 DPI를 가진 디바이스만을 대상으로 하는 경우, 해당 DPI에 맞춰 1px = 1dp 대응만 고려하면 됩니다.
디바이스 예시: 해상도: 1080px x 1920px / DPI: 240
1️⃣ 240 dpi를 위의 px공식에 대입하면 변환 계수는 약 1.5, 즉 240 dpi에서는 1dp = 1.5px
2️⃣ 사실 원래 디바이스와 동일하게 1080px x 1920 px로 작업해도 상관없지만 그렇게 되면 개발자가 피그마 캔버스의 px을 dp로 변환해서 코드를 작성해야 함. (오히려 좋아..?)
3️⃣ 이때, 캔버스 사이즈를 대응해서 개발하지 않는다면 300px으로 기대했던 크기가 300dp와 다를 수 있다는 점이 문제.
오른쪽 하단의 240 dpi 상황에서는 같은 300이라는 수치를 사용해도 figma의 캔버스에서 차지하고 있는 크기보다 1.5배 커지는 문제가 발생할 수 있음.
160 dpi나 240 dpi나 같은 크기의 입구를 가진 바구니(1dp)지만 240 dpi 바구니는 깊이가 1.5배 더 깊기 때문에 두 바구니를 털어놓을 때(px로 변환할 때) 1.5배 더 많은 내용물이 나오게 됨.
Figma에서 디자인한 모든 요소 개발 시 동일한 dp 값을 사용하기 위해서는 캔버스 크기를 대응해 주면 됩니다.
▶️ Figma 캔버스 크기:
참 쉽죠? 결국 1920px은 1280dp가 된다는 말이니, 애초에 Figma 캔버스 사이즈를 1280px로 작업하면
px과 dp가 1대 1 대응을 하기 때문에 별도의 변환이 필요 없게 되어 효율적이라고 말할 수 있을 것 같습니다.
앱을 플레이스토어에 업로드하여 다양한 DPI를 가진 디바이스에서 지원하려면, 1px = 1dp 대응을 기반으로 디자인 캔버스를 설정하고, 안드로이드 시스템의 자동 변환을 활용해야 합니다.
즉, 자동 변환되기 때문에 첫 캔버스만 잘 잡아두면 사이즈로는 별로 신경 안 써도 됩니다.
Figma 캔버스 크기 설정:
기준 DPI: 보통 MDPI (160 dpi)를 기준으로 설정하나, 1px = 1dp로 작업하면 기준 DPI에 관계없이 일관성을 유지할 수 있습니다.
디자인 작업:
모든 UI 요소를 dp 단위로 설정하며, 1px = 1dp로 작업합니다.
개발자와의 협업:
개발자는 Figma에서 디자인한 px 값을 그대로 dp 단위로 사용합니다. 안드로이드 시스템이 각 디바이스의 DPI에 맞춰 dp를 px로 자동 변환합니다.
사실 캔버스 사이즈야 뭐 디자이너든 개발자든 시점이 언제든 변환만 잘하면 되는 문제이고, 저희 회사처럼 하드웨어가 정해져 있지 않다면,
어차피 전체 dpi 대응을 위해서 기준점으로 MDPI 하나만 잘 잡으면 추가적인 대응 필요 없이 개발단에서 해결할 수 있는 문제이기 때문에, 상황에 따라 애초에 이런 게 문제가 안 될 수도 있다고 생각해요.
다른 OS와 마찬가지로 디자인에 있어서 정말 중요한 것은 이미지와 같은 리소스 대응과 전달이라고 생각합니다.
딱 하나만 기억하면 되는데, svg 같은 vector는 크게 상관없고 “png나 webp 같은 이미지는 무조건 가장 큰 해상도인 XXXHDPI를 기준으로 export 한다”입니다.
그냥 간단하게 figma 디자인 캔버스 기준으로 3~4 배수해도 깨지지 않는지 확인하고, 4 배수된 이미지를 기준으로 전달드리면 모두가 행복할 수 있답니다~!
저는 이번에 안드로이드 작업을 하면서 가장 궁금했던 게, 피그마로 만든 Variable은 어떻게 전달드려야 하지? 였습니다.
저는 프로젝트를 시작하면 웬만하면 배리어블로 색상과 텍스트를 정의해 놓고, 정의해 놓은 토큰들로만 디자인을 하는 것을 굉장히 선호하는데, 문제는 모든 개발자가 디자인 토큰의 중요성에 공감하지 못한다는 점과 대부분의 경우 디자인 토큰을 고려할 시간적 여유가 충분하지 않다는 점이죠.
그래서 가능하다면 개발자분이 큰 노력 없이 바로 정의된 토큰을 사용하게끔 전달하는 것이, 일관된 토큰과 시스템 규칙을 보존할 수 있는 가장 현명한 방법이라고 생각해요.
그래서 보통의 경우에는,
Figma Variable ➡️ json ➡️ style-dictionary로 파싱 ➡️ css
이 방식으로 변환해서 사용할 수 있도록 피그마의 variable을 json으로 전달드리는 편인데..
json으로 전달드려도 안드로이드에 맞게 파싱 하려면 수작업이 필요하다는 이야기를 듣고, 1차 좌절을 하게 되었습니다. 왜냐하면 이 프로젝트 자체가 거의 일주일 만에 개발을 하는 상황이어서 도저히 수작업에 시간을 쓸 여지가 없어 보였기 때문입니다.
그래서 우선 안드로이드에서 색상 변수를 활용하는 형식을 확인했고, 이 형식에 맞게 파싱을 도와주는 친구를 찾다 보니 어렵지 않게 zeplin을 만나게 되었고 무작정 그냥 써봤는데 정말 친절하게 잘 구성되어 있어서 굉장히 쉽게 figma에서 zeplin으로 export 해서 token을 xml형식으로 전달드릴 수 있었습니다.
우측 빨간 박스 부분이 figma에서 불러온 색상 variable을 android에 맞게 변환되어 나오는 값이고, 색상뿐만 아니라 폰트나 다른 토큰 역시 자동으로 변환되어서 매우 용이합니다.
이밖에도 android의 viewModel 메커니즘을 이해했을 때, 프로덕트를 디자인하는 입장에서 어떤 점에서 도움이 되는지, 안드로이드의 모션은 어떤식으로 구현되고 어떻게 시안을 준비해야 하는지 등 재밌는(?) 콘텐츠들이 남아 있지만, 이 부분은 상당히 까다로운 내용이라 이번 글 반응이 좋다면 정리해서 올려보겠습니다 후후..
사실 요 내용은 저처럼 처음 OS환경을 접한 디자이너가 효율적으로 작업에 착수할 수 있기를 바라면서사내의 OS별 디자인 가이드를 작성하는 과정에서 일부분만 가지고 왔답니다.
아무튼 이번 과정을 간단히 회고해 보자면.. 앞단에서 가장 먼저 얘기한 것처럼,
Zeplin을 썼으면 같은 디자인 시안을 사이즈에 맞게3번이나 다시 그리는 등 시행착오를 줄이고 더 빨리 대응할 수 있었을 것 같다는 아쉬움은 있지만, 모든 땅바닥에 헤딩하는 시도들이 그렇듯 의미가 없던 경험은 아니라고 생각해요.
덕분에 px과 dp개념도 어느 정도 이해했고, Android 자체를 찾아보면서 UI가 렌더링 되는 로직도 흥미로웠고, 특히 Material Design 정독하면서 정말 탄탄하게 만들어졌구나 놀라기도 했습니다.
또한, 안 그래도 디자인 챕터 사이드에서 인터랙션 가이드와 핸드오프에 대해 이야기하고 있었는데, Material Design의 motion guide를 보면서 조금 더 구체화할 수 있어서 좋았던 것 같습니다.
조만간 비슷하지만 다른 이야기로 다시 돌아오겠습니다. 아편 같은 연휴 모두 잘 보내시기를~!