Android TabLayout, Viewpager2 selected tab text bold
tablayout과 viewpager2 그리고 그에 따른 fragment를 사용하면 간단하고 탭 이동과 다른 화면을 보여줄 수 있다.
tablayout에서 기본적으로 선택된 탭의 커스텀을 제공하고 있지만, bold처리만은 되어있지 않다.
이 기능은 리스너를 통해 직접 구현을 해야 한다.
구글에 검색을 하면 많은 자료들이 보이고 대부분 tablayout의 리스너를 통해 변경을 하고 있는데,
내 경우 스와이프시 잠깐 반짝이는 현상이 보였다.
아마 bold처리와 bold해제에서 문제가 발생한 듯 싶은데 이를 tablayout의 리스너를 통해서는 잡을 수 없었다.
그래서 방법을 바꿔 viewpager2의 registerOnPageChangeCallback 을 통해 바꿔보았고 제대로 동작을 하였다.
binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageScrollStateChanged(state: Int) {
if (state == 0) {
val tabSize = (binding.tabs.getChildAt(0) as ViewGroup).size - 1
for (i in 0..tabSize) {
if (i == selectPosition) {
setSelectedTxtType(selectPosition, true)
} else {
setSelectedTxtType(i, false)
}
}
}
super.onPageScrollStateChanged(state)
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels)
}
override fun onPageSelected(position: Int) {
selectPosition = position
super.onPageSelected(position)
}
})
onPageSelected에서 선택된 탭의 포지션 값을 저장해 두어야 한다.
여기서 처리를 안한 이유는 스크롤을 바꿀 때 계속해서 호출을 하여 위와 동일한 이슈가 발생해서이다.
bold처리는 onPageScrollStateChange에서 해야 하는데 state값이 0이면 탭 이동이 완료된 상태이다.
이는 로그를 찍어보면 간단히 확인해 볼 수 있다.
여기서 저장된 포지션값을 해당 탭 레이아웃의 포지션에 대응하여 해당 tab을 bold처리하고 나머지는 다시 초기화 시키면
이동된 탭만 bold처리과 되고 나머지는 원래의 폰트로 돌아온다.
private fun setSelectedTxtType(position: Int, isBold: Boolean) {
val tabLayout =
(binding.tabs.getChildAt(0) as ViewGroup).getChildAt(position) as LinearLayout
val tabTextView = tabLayout.getChildAt(1) as TextView
tabTextView.setTypeface(null, if (isBold)Typeface.BOLD else Typeface.NORMAL)
}
bold처리 코드는 위와 같다.
결론은 스크롤 시 계속 호출하면 문제가 발생하여 viewpager2의 콜백을 통해 스크롤이 완료된 시점에서 bold처리를 해주면 된다.