[Android] 안드로이드 개발자의 디자인 시스템(모듈) 개발기

개요

어쩌다 디자이너 없이 디자인 시스템을 구축하게 되었느냐 물으신다면 대답해 드리는 게 인지상정! 단연코 가장 큰 이유는 역시 ‘디자인의 통일성’이라고 할 수 있다. 팀의 특성상 Sample App이나 Test App 등, product라고 할 수 없지만 공식적으로 ‘제공’해야 하는 애플리케이션들이 많은 편이다. 이 앱들은 필요에 의해 지속적으로 제공되기도 하지만 단발성으로 제공되기도 하기에 디자인이 중구난방인 상황이 발생한다. 이 부분에서 ‘디자인에 대한 고민 없이, 통일된 톤 앤 매너를 제공할 방법’으로 디자인 모듈의 필요성이 대두되었다.

요약하자면 다음과 같다.

  • Product는 아니나 임시로 제공되는 앱(SampleApp, Test App 등)의 디자인이 통일되었으면 좋겠다는 니즈
  • 디자인에 들어가는 비용 최소화
  • (가능하다면) iOS 앱도 유사한 느낌으로 제공할 수 있는 발판 마련

필요한 건 알겠고, 어떻게 하지…?

막상 시작하려 보니 고민할 포인트가 산더미처럼 쌓여 있었다. 그중 날 가장 헷갈리게 만든 두 가지 항목을 소개하려 한다. (이 두 가지가 전부였던 것 같기도 하고…?)

Material 3, 어디까지 포함해야 하는가 🧐

디자인 모듈이 언급되었을 때, 해당 모듈이 포함될 테스트 앱에 Material 3 또한 적용해 보기로 하였다. 처음에는 ‘그럴 수 있지’의 생각이었으나, 막상 디자인 모듈 설계와 Material 3을 놓고 진지하게 고민하다 보니 ‘여긴 어디, 나는 누구?’의 상태가 되었다.

이제 와서 생각해 보면 그때의 내가 바보였다. Material 3 또한 디자인 시스템의 일종이니 디자인 시스템을 설계하는 상황[1]에서는 충돌이 발생할 수밖에. 이럴 때엔 기준을 잘 잡아야 한다는 걸 알고 있었지만 처음이다 보니 Material 3을 어디에 포함해야 하는지, 어디까지 넣어야 하는지의 기준 잡기가 쉽지 않았다.

처음에는, 찝찝함을 뒤로하고 이미 만들어진 디자인 시스템인 Material 3에 우리 브랜드를 녹여 보았다. 음, 좋은 시도였다고 생각한다. 가장 빠르게 만들 수 있는 방법이었으니까. 그러나 적절한 방법은 아니다. Material 버전이 업데이트된다면? Material 시스템에 종속된다는 건 결국 Material 버전에 따라 누군가는 이 디자인 모듈을 계속 수정해야 한다는 것을 의미한다.

너무 당연하지만, Material 3은 디자인 모듈이 아닌 모앱에 포함되어야 한다는 결론에 도달했다. 대신, Material 3 Theme을 쉽게 적용할 수 있도록 color set의 기본값을 지정하는 정도로 마무리했다. 재정의 Component 또한 Material 3과의 종속성을 끊어내고 AppCompat에 의존하도록 변경하였다.

네이밍, 네이밍, 네이밍!!! 🔥

하, 진짜, 할 말은 많지만 하지 못할 정도로 네이밍과 멱살 잡고 싸웠다. color부터 icon, selector 등 파일 하나 만들 때마다 수없이 고민했다. 단연코 탑은 dimen! 중복되는 값들이 많아 padding, margin 대신 spacing으로 통일하였는데 '어떤 값을 사용해야 할지 모르겠다’는 피드백을 받았고, 이 피드백을 통해 사용자 입장을 더 깊이 생각해 볼 수 있었다.

모듈 사용자 입장에서는 몇 가지 단어를 적어 보고 추천되는 값을 기반으로 적용할 텐데, ‘spacing’ 이나 ‘padding’ 만으로는 이게 ‘어디에’ 사용될 값인지 알 수 없다는 게 가장 큰 문제였다. 적은 리소스로 최대한 많은 범위를 포함하고 싶어 애매하게 정한 네이밍이 사용성을 해치는 결과를 낳았다. 🥲

위 피드백에 덧붙여, UI 적용 케이스마다 정해진 값이 있으면 편할 것 같다는 의견을 함께 받았다. 곰곰이 생각해 보니 이 방향이 맞았다. 디자인 모듈 개발 목적 중 하나는 '비용 최소화’도 있었기 때문에, 사용자 입장에서 고민할 시간을 줄이는 것 또한 모듈의 목표가 되는 게 맞다.

둥글둥글 애매모호했던 표현을 조금 더 명확하게 다듬었다. 예를 들어, default_start_spacing 과 같은 모호한 표현 대신 default_list_item_inner_padding_start 와 같이 ’사용 케이스’와 '어떤 값’인지 분명히 알 수 있도록 의도했다.


그래도 어쩌겠습니까, 해내야죠

0부터 시작하는 일은 몇 번을 마주해도 어렵지만 약간의 요령이 생기긴 하나 보다. 엄두가 나지 않을 땐 쪼개고 쪼개고 또 쪼개서 할 수 있는 것부터 하려고 노력한다. 쪼개고 쪼개진 것들이 모이면 덩어리가 될 테니까!

할 수 있는 것 먼저 처리하자

  1. 아이콘 리소스 집어넣기

    • 쉽고 빠르게 할 수 있는 단순 노동. 아이콘은 사내에 공식 배포된 리소스가 있었기에, svg로 다운로드 후 xml로 변환하여 넣어 주었다.
    • 네이밍은 ic_mail 과 같이 접두사로 ic 를 사용했다.
  2. color 정의하기

    • 위 문단에서 언급한 것처럼 Material 3 기준 color setup 리소스와 함께 주로 사용되는 투명 색상과 기본적으로 사용되는 브랜드 컬러를 추가했다.
  3. 폰트를 넣어 볼까?

    • NO! 굳이 몸집 키울 이유가 없다. 폰트는 필요한 경우 모앱에서 넣기로 해!

Size, 너도 문제야

끝없는 싸움이었다. 🫠 모든 사이즈 정의가 불가하기 때문에 바로 사용해야 하는 값들과 함께 여기저기 막 사용할 수 있는 사이즈를 몇 가지 지정했다. 간략히 나열하자면 radius, button_text_size, image_size, text_size, line_height 정도?

그 외 몇 가지를 더 추가했는데, 이 값은 Material 3 dimen을 보고 힌트를 얻었다. label 이나 headline 등, 만만하게 막 쓸 수 있는 값들을 조금 더 추가했다. 그리고 이 값들로 커버할 수 없는 값은 dimen 이라는 친구로 통일했다. 예를 들어 dimen_28dp 를 의미한다. (실제 dp = 접미사 * 4)

버튼, 너라도 많이 만들어야겠다

Material 3을 기준으로 AppCompat을 상속하여 Custom Button set을 정의했다. 아래 리스트가 재정의한 버튼들이다.

  • Button
    • Button.Filled
    • Button.Fit
  • Button.Rounded
    • Button.Rounded.Filled
  • Button.FullyRounded
    • Button.FullyRounded.Filled
  • TextButton - AppCompatButton.Borderless 를 재정의함
    • TextButton.Fit
  • OutlinedButton
    • OutlinedButton.Rounded
    • OutlinedButton.FullyRounded
  • ImageButton
    • ImageButton.Small
    • ImageButton.Medium
    • ImageButton.Large

버튼 정의시 배경과 selector 정의[2]가 필요하다. 이 부분은 캡쳐로 대신한다.


마무리하며

작업이 끝났을 때 바로 회고하는 게 가장 좋다는 걸 알면서도 늘 게으름이 이긴다. 그나마 다행인 건 작업 중 적어둔 메모의 존재와 중간중간 거친 정리 과정이겠지? 미루고 미루던 디자인 모듈 개발기를 완성할 수 있어 뿌듯한 일요일이다. 🍀 거창하고 대단하다고 할 순 없지만… AppCompat이 나온(나올 수밖에 없었던) 배경과 디자인 시스템을 이해해 보는 소중한 경험이었다. 🫡


참고




  1. 심지어 Material 3 가이드를 참고하여 설계하는 중이었음 🫥 ↩︎

  2. selector 정의 안 해도 되지만… 안 하면 onClick event 발생시 ripple 효과가 안 생김 ↩︎

Share