Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Why is onTabSelected being called when tabs are created?

When the action bar has tabs, I've noticed that onTabSelected is called when the activity loads on screen. It also is being called whenever an orientation change occurs. My code queries the database depending on the tab being selected, and displays the query results to the loaded layout.

My problem is when saving tab state, and the current selected tab is 1 or higher, on restore state, since onTabSelected is called by default on the 0 tab, it will be called again when restored state tab is 1 or higher. This makes database query on tab 0 useless.

How to configure android that onTabSelected isn't called on tab creation or at least detect that this call is default and not user triggered?

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    int tabPos = tab.getPosition();
    switch(tabPos) {
    case 0:
        // query database and display result
        break;
    case 1:
        // a different query and display result
        break;
    case 2: ...
    }
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    if(savedInstanceState.containsKey(STATE_SELECTED_TAB)) {
        getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_TAB));
    }
    super.onRestoreInstanceState(savedInstanceState);
}

@Override
public void onSaveInstanceState(Bundle outState) {
    outState.putInt(STATE_SELECTED_TAB, getActionBar().getSelectedNavigationIndex());
    super.onSaveInstanceState(outState);
}

Added complication: When the current selected tab is 0, and the orientation changes, onTabSelected is still called twice! Once when the tabs are initially created, and 2nd time when onRestoreState restores the saved tab selected state, even though it is 0.

What I originally supposed was that onTabSelected was called twice, but I was mistaken. It was my fragment onCreateView being called twice, some errors in fragment transaction that added the same fragment twice on orientation change. onTabSelected is called once, and restore state calls onTabReselected is called too when the restored tab is also 0.


After scouring SO and google, I've found this question to have similar cause of problem. Creating ActionBar tab also calling its selectTab functions

like image 774
Poly Bug Avatar asked Aug 30 '14 00:08

Poly Bug


2 Answers

So after reviewing the reference docs on ActionBar from Google's Android site, addTab method is the one responsible for calling onTabSelected by default.

public abstract void addTab (ActionBar.Tab tab)

Add a tab for use in tabbed navigation mode. The tab will be added at the end of the list. If this is the first tab to be added it will become the selected tab.

Parameters
  tab     Tab to add

Incidentally, other overloaded methods exist that do not call onTabSelected.

public abstract void addTab (ActionBar.Tab tab, boolean setSelected)

So I used these alternative methods instead and it fixed the problem. However, once the tabs are displayed, the first tab may appear selected even though it's not. Clicking on it will call onTabSelected and not onTabReselected.

like image 170
Poly Bug Avatar answered Oct 18 '22 07:10

Poly Bug


I solved it in this way:

Call setupWithViewPager before tabLayout.addOnTabSelectedListener

tabLayout.setupWithViewPager(viewPager)

tabLayout.addOnTabSelectedListener(object :  TabLayout.OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab?) {....}
.....
}

because when you call setupWithViewPager, this will internally call setOnTabSelectedListener(new ViewPagerOnTabSelectedListener(viewPager));

so you better call it before adding tabSelect Listener to tabLayout

like image 21
Zohab Ali Avatar answered Oct 18 '22 07:10

Zohab Ali