Sunday 4 November 2012

Forcing Embedded tabs in ActionBar Sherlock

I recently spent some time trying to find a way to prevent Action Bar tabs from appearing on a second line below the Action Bar. I wanted them inlined in the Action Bar itself. Strangely, this is default behaviour in landscape mode but in portrait mode the tabs are always placed on a second line taking up valuable screen estate and frankly, for the small number of tabs I needed (just 2), looking ugly.

This behaviour occurs even when there is plenty of room for the tabs in the actionbar. There were various questions on Stack Overflow asking for solutions to this issue - including this one (EDIT: answer now added). I eventually found the answer buried in the answers to this rather unhelpfully titled question. I take no credit for this solution (I think 'hack' might be a better word!), It appears to originally come from poster 'Roberto' in this Google Groups thread. I have reproduced it here for reference.

//pre-ICS
if (actionBarSherlock instanceof ActionBarImpl) {
    enableEmbeddedTabs(actionBarSherlock);

//ICS and forward
} else if (actionBarSherlock instanceof ActionBarWrapper) {
    try {
        Field actionBarField = actionBarSherlock.getClass().getDeclaredField("mActionBar");
        actionBarField.setAccessible(true);
        enableEmbeddedTabs(actionBarField.get(actionBarSherlock));
    } catch (Exception e) {
        Log.e(TAG, "Error enabling embedded tabs", e);
    }
}

//helper method
private void enableEmbeddedTabs(Object actionBar) {
    try {
        Method setHasEmbeddedTabsMethod = actionBar.getClass().getDeclaredMethod("setHasEmbeddedTabs", boolean.class);
        setHasEmbeddedTabsMethod.setAccessible(true);
        setHasEmbeddedTabsMethod.invoke(actionBar, true);
    } catch (Exception e) {
        Log.e(TAG, "Error marking actionbar embedded", e);
    }
}
Sure it a bit of a gross hack using reflection, but if embedded tabs are allowed in landscape they really ought to be allowed in portrait too, provided there is space. The functionality is there so I can't see why Google (and hence ABS) have 'hidden' it.

No comments:

Post a Comment