How does action_bar_embed_tabs exactly work in Android?

╄→гoц情女王★ 提交于 2019-12-22 08:37:17

问题


I have tabs in an actionbar. On large screens the tabs are embed to the actionbar but on small screens the are not. I want to control the tabs manual so i can separate the tabs from the actionbar. I tried to set abs__action_bar_embed_tabs but that didn't work

<resources>
    <bool name="abs__action_bar_embed_tabs">false</bool>
</resources>

回答1:


I know this is an old post, however I would like to add a solution using action_bar_embed_tabs for future readers.

Create the below method (do take care of the imports),

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();
    }

    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 src="http://www.blogc.at/wp-includes/images/smilies/icon_wink.gif" alt=";-)" class="wp-smiley">
            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) {}
}

Then call this like below,

  1. If you want tabs to appear inside the action bar,

    setHasEmbeddedTabs(actionBar, true);

  2. If you want tabs to appear separate/ below the action bar,

    setHasEmbeddedTabs(actionBar, false);

All credits to Cliff.




回答2:


I found a solution to separate the tabs in code.

private void embeddedTabs(Object actionBar, Boolean embed_tabs) {
    try {
        if (actionBar instanceof ActionBarWrapper) {
            // ICS and forward
            try {
                Field actionBarField = actionBar.getClass()
                        .getDeclaredField("mActionBar");
                actionBarField.setAccessible(true);
                actionBar = actionBarField.get(actionBar);
            } catch (Exception e) {
                Log.e("", "Error enabling embedded tabs", e);
            }
        }
        Method setHasEmbeddedTabsMethod = actionBar.getClass()
                .getDeclaredMethod("setHasEmbeddedTabs", boolean.class);
        setHasEmbeddedTabsMethod.setAccessible(true);
        setHasEmbeddedTabsMethod.invoke(actionBar, embed_tabs);
    } catch (Exception e) {
        Log.e("", "Error marking actionbar embedded", e);
    }
}

But now I have a new problem. The tabs don't fill the tabbar completely. Actionbar tabs don't fill the tabbar




回答3:


In ActionBarSherlock, abs__action_bar_embed_tabs is used to determine whether the Tabs should be embed in ActionBar, and the value is stored in two files.

  1. In values/abs__bools.xml. It is false.
  2. In values-w480/abs__bools.xml. It is true.

This means Tabs will be embed only if the width of device is bigger than 480dp. I think such configuration has already satisfied your requirement.

If you want to control it all by yourself, you can just create your own values folder with any configuration qualifier you want, and override this bool value.

EDIT: OK, i tried. It cannot work. In fact, it only work under HONEYCOMB. Since before honeycomb sherlock action bar has it's own ActionBarImpl, so you can change this value. But in native implementation of ActionBar, this value is com.android.internal.R.bool.action_bar_embed_tabs and cannot be modified.

So.. although i do not approve reflection mechanism, but maybe it's the only way to achieve your target.

I'm very sorry for making you confused.




回答4:


in this file: ActionBarImpl.java

on private void setHasEmbeddedTabs(boolean hasEmbeddedTabs)

change the value:
mHasEmbeddedTabs = hasEmbeddedTabs;

to:
mHasEmbeddedTabs = false;



来源:https://stackoverflow.com/questions/13581155/how-does-action-bar-embed-tabs-exactly-work-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!