Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force splitting ActionBar's Tab and Title/Home/Menu?

Tags:

android

I'm using ActionBar's tab feature with a PageViewer, but meet a problem. On my Nexus 7, the tabs show like this:

On Nexus 7

You can see the title is cut due to lacking space. But on HTC Incredible S with Android 4.0 it shows like:

enter image description here

And this is what I want. I in factr want the tab bar be placed on bottom of screen though, but splitting to two rows and both on top is acceptable.

Does anyone know how to force app on Nexus 7 also split tab bar to another row? Thank you!

like image 979
Romulus Urakagi Ts'ai Avatar asked Aug 22 '12 05:08

Romulus Urakagi Ts'ai


3 Answers

AFAIK, the action bar alone decides whether or not to put the tabs on a second row, and we cannot influence that.

Also, bear in mind that in many cases, your tabs will not appear at all, replaced by a drop-down list -- basically, Android converts tab navigation to list navigation.

If you want to ensure that your tabs are always tabs, and are always below the action bar, remove the tabs from the action bar and switch to using a ViewPager for your content, with either PagerTabStrip (from the Android Support package, where ViewPager comes from) or the tab indicator from the ViewPagerIndicator project for the tabs themselves. As a side benefit, your contents are now horizontally swipe-able to move between tabs, which is a popular approach nowadays.

I in factr want the tab bar be placed on bottom of screen though

Please bear in mind that this violates the Android Design guidelines: http://developer.android.com/design/patterns/pure-android.html

like image 90
CommonsWare Avatar answered Oct 07 '22 05:10

CommonsWare


I use this to force ActionBar stacked or unstacked tabs from Gingerbread to KitKat.

Modded From: http://www.blogc.at/2014/01/23/android-tabs-appear-above-or-below-actionbar/

http://i.imgur.com/fO0Vk3V.png

setHasEmbeddedTabs(mActionbar,false);

    public static void setHasEmbeddedTabs(Object inActionBar, final boolean inHasEmbeddedTabs)
    {
        // get the ActionBar class
        Class<?> actionBarClass = inActionBar.getClass();

        // if it is a Jelly Bean implementation (ActionBarImplJB), get the super class (ActionBarImplICS)
        if ("android.support.v7.app.ActionBarImplJB".equals(actionBarClass.getName()))
        {
            actionBarClass = actionBarClass.getSuperclass();
        }

        // if Android 4.3 >
        if ("android.support.v7.app.ActionBarImplJBMR2".equals(actionBarClass.getName())){
            actionBarClass = actionBarClass.getSuperclass().getSuperclass();
        }

        try
        {
            // try to get the mActionBar field, because the current ActionBar is probably just a wrapper Class
            // if this fails, no worries, this will be an instance of the native ActionBar class or from the ActionBarImplBase class
            final Field actionBarField = actionBarClass.getDeclaredField("mActionBar");
            actionBarField.setAccessible(true);
            inActionBar = actionBarField.get(inActionBar);
            actionBarClass = inActionBar.getClass();
        }
        catch (IllegalAccessException e) {}
        catch (IllegalArgumentException e) {}
        catch (NoSuchFieldException e) {}

        try
        {
            // now call the method setHasEmbeddedTabs, this will put the tabs inside the ActionBar
            // if this fails, you're on you own <img class="wp-smiley" alt=";-)" src="http://www.blogc.at/wp-includes/images/smilies/icon_wink.gif">
            final Method method = actionBarClass.getDeclaredMethod("setHasEmbeddedTabs", new Class[] { Boolean.TYPE });
            method.setAccessible(true);
            method.invoke(inActionBar, new Object[]{ inHasEmbeddedTabs });
        }
        catch (NoSuchMethodException e)        {}
        catch (InvocationTargetException e) {}
        catch (IllegalAccessException e) {}
        catch (IllegalArgumentException e) {}
    }
like image 27
zeroprobe Avatar answered Oct 07 '22 06:10

zeroprobe


If you need to support phones and tablets and don't want to use separate implementation you can put this in your activity:

@Override
public Resources getResources() {
    if (mResourcesImpl == null) {
        mResourcesImpl = new ResourcesImpl(super.getResources());
    }
    return mResourcesImpl;
}

class ResourcesImpl extends Resources {
    private Resources mResources;
    private Set<Integer> mActionBarEmbedTabsIds = new HashSet<Integer>();

    ResourcesImpl(Resources resources) {
        super(resources.getAssets(), resources.getDisplayMetrics(), resources.getConfiguration());

        mResources = resources;

        String packageName = getPackageName();
        mActionBarEmbedTabsIds.add(mResources.getIdentifier("abc_action_bar_embed_tabs", "bool", packageName));
        mActionBarEmbedTabsIds.add(mResources.getIdentifier("abc_action_bar_embed_tabs_pre_jb", "bool", packageName));
        mActionBarEmbedTabsIds.add(mResources.getIdentifier("action_bar_embed_tabs", "bool", "android"));
        mActionBarEmbedTabsIds.add(mResources.getIdentifier("action_bar_embed_tabs_pre_jb", "bool", "android"));
        mActionBarEmbedTabsIds.remove(0);
    }

    @Override
    public boolean getBoolean(int id) throws NotFoundException {
        if (mActionBarEmbedTabsIds.contains(id)) {
            return areActionBarTabsEmbed(); // stacked ot embed goes here
        }
        return super.getBoolean(id);
    }
}
like image 1
MatrixDev Avatar answered Oct 07 '22 04:10

MatrixDev