Search code examples
androidandroid-layoutandroid-tablayout

Enabling TabLayout is not enabling onTouchEvents - Tabs not clickable


I have simple TabLayout with 2 Tabs. In one moment I need to disable TabLayout and disable user interaction with Tabs too.

But if I want to enable them again, it is not working. Tab indicator and alpha is changed back to normal, but tabs are not reacting to user interaction.

select() function is reacting with listener normally, only physical interaction with Tabs on screen is not working.

Anyone have this problem?

Functions to enable/disable Tabs (some parts are just visual change to disable state - TabLayout will not grey out if you disable it like Button)

private fun deactivateTabs(){
        tabs.apply {
            selectTab(null)
            isEnabled = false
            touchables?.forEach {
                it.isEnabled = false
                it.alpha = .5f
            }
            setSelectedTabIndicatorColor(ContextCompat.getColor(tabs.context, R.color.grey))
        }
    }

    private var lastSelected: Int = -1
    private fun activateTabs(){
        tabs.apply {
            isEnabled = true
            touchables?.forEach {
                it.isEnabled = true
                it.alpha = 1f
            }
            setSelectedTabIndicatorColor(ContextCompat.getColor(tabs.context, R.color.colorTab))

            if (lastSelected == -1){
                //default tab
                getTabAt(0)?.select()
            } else {
                getTabAt(lastSelected)?.select()
            }
        }
    }

Also childCount is different from tabCount in my TabLayout which is totally weird behavior in Android. I added tabs to my layout xml inside TabLayout so it should be counted as its children. but childCount is 1 and tabCount is 2.

I dont get this behavior at all.


Solution

  • After few hours I solved this issue by saving Tabs as touchable Views.

    I could not change state directly. I had to save touchables, which created clone (with pointer). And I changed those instead of real ones.

    Updated code:

    private fun deactivateTabs(){
            tabs.apply {
                tabsAsTouchables = touchables
                tabsAsTouchables.forEach {
                    it.isEnabled = false
                    it.alpha = .5f
                }
                setSelectedTabIndicatorColor(ContextCompat.getColor(tabs.context, R.color.grey))
            }
        }
    
        private var lastSelected: Int = -1
        private var tabsAsTouchables: List<View> = emptyList()
        private fun activateTabs(){
            tabs.apply {
                tabsAsTouchables.forEach {
                    it.isEnabled = true
                    it.alpha = 1f
                }
                setSelectedTabIndicatorColor(ContextCompat.getColor(tabs.context, R.color.colorTab))
    
                if (lastSelected == -1){
                    //default tab
                    getTabAt(TAB_HISTORY)?.select()
                } else {
                    getTabAt(lastSelected)?.select()
                }
            }
        }