때로는 과감히 소스를 까보자

대략 3년 전쯤, 잠시 내 손을 떠났던 프로젝트의 코드를 수정하는 동료가 기존에 (아마도) RadioButton으로 구현했던 Tab 버튼영역 UI를 TabLayout을 사용해 구현하는 방식으로 바꾸면서 각 탭 버튼들의 폭이 디바이스에 따라 다르게 그려지는 현상이 나타난다며 도움을 요청해왔다.

화면 디자인상 Tab은 통짜 이미지를 슬라이스해서 버튼을 만들고, 항상 가로를 가득 채우도록 확대/축소 되는 식이어서 정확히 지정된 폭으로 그려지지 않으면 만들다만 것 같은 화면이 되어버린다.

그런데 TabLayout을 적용하니 각 버튼이 지정된 폭을 무시하고 모든 버튼이 같은 폭으로 그려지고 있었다. 어떤 버튼은 여백이 나오고 어떤 버튼은 잘려서 보였다.

모드를 scrollable로도 해보고 fixed로도 해보고 이런 저런 속성 값들을 아무리 바꿔봐도 폰과 태블릿이 서로 번갈아가며 이상한 UI를 그리고 있었다. 도무지 답답해서 그냥 TabLayout 소스코드를 찾아봤다. 그랬더니 Scrollable 모드에서는 design_tab_scrollable_min_width 리소스 값을 읽어와서 최소 폭을 지정하고 있었고 그래서 실제 폭이 그보다 작으면 아무리 다른 값을 지정해도 적용이 안되고 있었던 것이다. 원래 각 버튼의 폭은 픽셀값을 기준으로 계산하도록 되어있었는데 이 리소스의 값은 dp로 지정되어있어서 폰에서 보여줄 때는 태블릿보다 큰 픽셀값이 최소폭으로 지정되고 있었고, 그래서 태블릿과는 달리 여백이 생기는 현상이 나타났던 것이다. 이 속성을 리소스 파일에서 -1px로 오버라이드했더니 의도대로 결과가 나오는 것을 확인했다.

지금 생각해보면 tabMinWidth 속성을 사용해도 되었을 것 같지만 당시에는 거기까지 살펴보진 못했던 것 같다.

작년에는 RadioGroup의 onCheckedChange 리스너가 한 번의 check()에 대해서 자꾸 여러 번 호출되는 현상이 있었는데 역시 소스코드(+스택오버플로)를 참고해서 적절한 해결책을 찾았었다.

이 외에도 여러가지 View를 다루다보면 문서가 완전히 커버하지 못하는 케이스들이 많다. 모든 설정값에 대한 모든 동작을 전부 문서화하는 것은 현실적으로 불가능하고, View 구현체별 주요 활용 용도 외에는 사전에 설계하기도 어렵기 때문에 어쩔 수 없이 undefined, undocumented로 남아있는 공백이 존재하게 된다. 이럴 때 ‘망할 구글’ ‘망할 안드로이드’ 하면서 스트레스 받아봤자 별 도움이 되지 않는다. 브레이크 포인트를 걸고 과감하게 F7(Step into)을 눌러보자.

Leave a Comment

Your email address will not be published. Required fields are marked *