OnClickListener on Tabs not working

Aracos picture Aracos · Jun 30, 2009 · Viewed 30k times · Source

Greetings,

I am trying to get the Click - event when clicking on the currently selected tab of my TabActivity. The onTabChangedHandler is only called whenever the tab is changed, not if the currently active Tab is clicked. The debugger tells me i have the onClickListener Registered for the TabWidget within my TabHost.

Am i registering for the wrong View?

Also, I am unable to create a Context Menu for the Tabs, only for its content, is this problem related?

public class TestDroidViewTab extends TabActivity 
                              implements TabContentFactory
                              , OnTabChangeListener, OnClickListener {

  private static final String LOG_KEY = "TEST";
  ListView listView;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      final TabHost tabHost = getTabHost();


      TabHost.TabSpec ts = tabHost.newTabSpec("ID_1");
      ts.setIndicator("1"); 
      ts.setContent(this);
      tabHost.addTab(ts);

      ts = tabHost.newTabSpec("ID_2");
      ts.setIndicator("2"); 
      ts.setContent(this);
      tabHost.addTab(ts);

      ts = tabHost.newTabSpec("ID_3");
      ts.setIndicator("3"); 
      ts.setContent(this);
      tabHost.addTab(ts);
      tabHost.setOnClickListener(this);
      tabHost.setOnTabChangedListener(this);
  }
  public void onClick(View v) {
      Log.d(LOG_KEY, "OnClick");
  }

  public void onTabChanged(String tabId) {
      Log.d(LOG_KEY, "OnTabChanged");
  }

Answer

Milo picture Milo · May 21, 2010

If you want to see that a particular tab is clicked, you need to add your listener to the tab itself, not the TabHost.

The hierarchy of views in a tab implementation is:

  • TabHost
    • TabWidget
      • (tab)
      • (tab)
    • FrameLayout

The tabs are added at runtime by calling: tabHost.addTab(tabHost.newTabSpec(""));

You can then get a handle to the individual tabs by calling: getTabWidget().getChildAt(4);

In essence, you are adding your OnClickListener to a child of the TabWidget. You can now pick up the clicks on your individual tab. However, this will override the default behavior which changes the content when a tab is clicked. So, to get your content to change, your OnClickListener will need to do that for you.

Here is a full example, which lets you intercept the click event, and change the content below the tab:

final String myTabTag = "My Tab";
final int myTabIndex = 3;

getTabHost().addTab( getTabHost().newTabSpec(myTabTag) );

getTabWidget().getChildAt(myTabIndex).setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        if (getTabHost().getCurrentTabTag().equals(myTabTag)) {
            getTabHost().setCurrentTab(myTabIndex );
        }
    }
});