본문 바로가기
안드로이드

[Android] 간격이 안 맞아요! (feat. Compose typography)

by algosketch 2024. 2. 27.

 

3명의 클라이언트 개발자를 부르는 마법의 단어

디자인 QA를 하다 보면 디자이너의 "이거 왜 이렇게 생겼지?"라는 말을 들어봤을 것이다. 물론 농담이다. 위 내용은 UI에 대한 얘기가 아니었다.

이 글에선 TextStyle을 이용해 폰트 시스템을 적용할 때 발생할 수 있는 문제와 해결 방법에 대해 공유할 예정이다. Compose의 Typography에 대한 기본적인 사용 방법에 대해서 설명하지는 않는다.

 

1. LineHeight만 적용했을 때 발생할 수 있는 문제

어쨋든 디자인 QA를 받았을 때 위와 같이 텍스트 사이의 간격에 대한 QA가 빗발쳤다. 그치만 나는 lineHeight까지 적용해줬는데, 왜 이런 문제가 생겼을까? 물론 수동으로 패딩 값을 맞춰주는 방법도 있지만 개발자라면 이런 반복 작업을 좋아하진 않을 것이다. iOS는 수동으로 해야한다던데...

TextStyle의 생성자에는 lineHeight도 있지만, lineHeightStyle이라는 다소 수상한 녀석이 존재한다. 

LineHeightStyle이라는 클래스를 살펴보면 trim이라는 파라미터가 존재하는데, default 값이 Trim.Both로 설정되어 있다. 즉, lineHeight만 설정하면 행간은 유지되지만, 첫 줄의 top 여백과 마지막 줄 bottom 여백이 잘리게 된다. 그 결과 텍스트가 포함된 컴포넌트에서 실제 디자인과 여백 차이가 발생하게 된다. trim 파라미터에 Trim.None을 전달하여 해결할 수 있다.

 

2. LineHeightStyle의 alinment?

그리고 alignment의 기본 값은 Proportional이고, 기본값으로 설정하면 다음 피드백을 받을 수 있다.

"글자와 아이콘의 정렬이 안 맞아요." 기존 방식에서는 추가 여백을 모두 잘라버렸기 때문에 Alignment.CenterVertically를 적용하면 가운데로 정렬되었다. 폰트 패딩을 잘라내지 않으면 lineHeight에 여백이 생기게 되는데, LineHeightStyle의 alignment는 lineHeight 내부에서 텍스트를 어떻게 정렬할 것인지를 나타낸다. 주석에서 확인할 수 있는 line이라는 표현이 조금 모호하다고 생각되는데, 공식문서를 살펴보면 좀 더 명확하게 이해할 수 있다.

Line에 해당하는 부분에 텍스트가 배치된다고 생각하면 된다. 따라서 lineHeightStyle 파라미터에 Alignment.center를 전달하게 되면 아이콘과 같은 선 상에 배치할 수 있다. Pretendard 폰트를 사용하고 있다면...

혹시나 필요할 시각보정을 위해 위와 같이 앱 내에서 사용하는 모든 폰트를 출력해 보았다. 사각형(아이콘 대체)은 lineHeight 크기와 동일하고, 폰트의 lineHeightStyle은 Time.None과 Alignment.Center를 적용했다. 배경을 넣지 않은 마지막 "다"는 Proportional와 Trim.Both가 적용되어 있다.

point 폰트는 Aggro font를 사용하고 있고, 나머지는 Pretendard가 적용되어 있다. Pretendard는 사각형과 비교했을 때 비교적 가운데 정렬이 잘 맞는 모습을 볼 수 있으나 Aggro font의 경우 약간 위쪽으로 치우쳐져 있는 것을 볼 수 있다. 이 경우 수동으로 padding을 넣어줄 수도 있겠으나 TextStyle의 BaseLineShift라는 파라미터를 살펴보자.

주석 설명을 읽어보면 multiplier * (baseline - ascent) 만큼 이동시킨다고 나와있다. multiplyer 값을 설정하여 텍스트를 정렬할 수 있다고 이해하면 된다. 다만, 같은 폰트 사이즈에 따라 다른 값을 적용해야 더 정확한 보정이 가능하다.

 

결론

텍스트 내부의 정렬은 LineHeight와 LineHeightStyle를 통해 설정할 수 있다. 하지만 이 두 가지를 설정했다고 하더라도 어떤 폰트를 사용하느냐에 따라 실제 보이는 결과물이 다를 수 있다. 때로는 시각 보정이 필요할 수 있고, 이 부분은 디자이너와의 상의해 원래 디자인 의도를 반영하는 것이 중요하다.