profile image

L o a d i n g . . .

반응형

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처리를 해주면 된다.

반응형
복사했습니다!