Hanbit the Developer

[Trouble shooting] TabLayout customView에 setTypeface를 주면 indicator의 값이 잠시 0으로 리셋되는 문제 본문

Mobile/Android

[Trouble shooting] TabLayout customView에 setTypeface를 주면 indicator의 값이 잠시 0으로 리셋되는 문제

hanbikan 2022. 8. 2. 12:52

문제 상황

 

 

해결 과정

1. 의심되는 코드들을 하나씩 주석처리 해가며, 어떤 코드를 지우면 문제가 발생하지 않는지 체크

범위를 좁히다보니, customView(as TextView)에 setTypeface() 함수에서 문제가 발생한다는 것을 발견하였다.

처음에는 indicator 관련 코드를 위주로 브레이크 포인트를 걸거나 주석 처리를 했었는데, 전혀 연관이 없어 보이는, 탭의 TextView와 연관이 있었다.

textView.setTypeface(
    null,
    if (isSelected) Typeface.BOLD else Typeface.NORMAL
)

 

2. setTypeface() 함수, Typeface 코드 분석

native code의 벽에 가로막혔으며, 시간을 너무 지체하면 안 되므로 여러 시도를 해보았다.(값을 의도적으로 바꾸어 setTypeface() 함수 내부에 있는 if문 브랜치들을 순차적으로 검사하였음) 그 결과 Typeface tf 파라미터에 기존 TextView의 typeface를 주게 되면 최초 1회 위 오류가 발생하는 것을 알게 되었다.

 

3. Log

textView.typeface에 대해 로그를 찍어보았는데, 오류가 발생할 때(최초 1회)는 setTypeface()를 하기 전과 후의 Typeface 인스턴스 주소가 달랐다. 따라서 setTypeface()를 '적절히' 호출하여 최초 1회에도 주소가 동일하도록 유도를 해주면 된다고 판단하였다.

이에 따라 setTypeface의 첫번째 인자(Typeface tf)에 여러 시도를 해보았고 결과적으로 아래와 같은 코드로 작성하면 문제가 발생하지 않는다는 결론이 나왔다.

textView.setTypeface(
    Typeface.DEFAULT_BOLD,
    if (isSelected) Typeface.BOLD else Typeface.NORMAL
)

 

마무리

아래 네이티브 함수로 막혀 원인을 깔끔하게 찾지 못하였다.

private static native void nativeForceSetStaticFinalField(String fieldName, Typeface typeface);

특히 이 문제를 복잡하게 만드는 것은, Tab의 customView의 typeface를 건드리는 방식에 따라서 전혀 연관이 없어보이는 indicator가 영향을 받는다는 것이다.