Android ActionBar在选项卡导航和ActionMode上锁定重叠

Android ActionBar在选项卡导航和ActionMode上锁定重叠,android,actionbarsherlock,Android,Actionbarsherlock,我对ActionBarSherlock有一个奇怪的问题,使用选项卡导航和动作模式 重复问题非常简单,我使用演示代码生成以下示例活动: import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.app.ActionBar.Tab; import com.actionbarsherlock.vie

我对ActionBarSherlock有一个奇怪的问题,使用选项卡导航和动作模式

重复问题非常简单,我使用演示代码生成以下示例活动:

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;

public class MainActivity extends SherlockFragmentActivity implements ActionBar.TabListener {
    private ActionMode actionMode = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        setTheme(com.actionbarsherlock.R.style.Theme_Sherlock);
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        for (int i = 1; i <= 2; i++) {
            ActionBar.Tab tab = getSupportActionBar().newTab();
            tab.setText("Tab " + i);
            tab.setTabListener(this);
            getSupportActionBar().addTab(tab);
        }

        actionMode = startActionMode(new TestActionMode());
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub
    }


    private final class TestActionMode implements ActionMode.Callback {

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            menu.add("Add").setIcon(android.R.drawable.ic_input_add).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
            menu.add("Search").setIcon(android.R.drawable.ic_search_category_default).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            // TODO Auto-generated method stub

        }

    }

}
import com.ActionBar sherlock.app.ActionBar;
导入com.actionbarsherlock.app.SherlockFragmentActivity;
导入com.actionbarsherlock.app.ActionBar.Tab;
导入com.actionbarsherlock.view.ActionMode;
导入com.actionbarsherlock.view.Menu;
导入com.actionbarsherlock.view.MenuItem;
导入android.os.Bundle;
导入android.support.v4.app.FragmentTransaction;
公共类MainActivity扩展SherlockFragmentActivity实现ActionBar.TabListener{
私有ActionMode ActionMode=null;
@凌驾
创建时的公共void(Bundle savedInstanceState){
setTheme(com.actionbarsherlock.R.style.Theme\u Sherlock);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION\u MODE\u选项卡);

对于(int i=1;i我最近遇到了同样的问题。在浪费了几天时间之后,我发现这种奇怪的行为是由中描述的UX缺陷引起的,事实上,与此无关

最可靠的解决方法似乎是使用反射来控制动作栏的渲染方式:

/**
 * On Android 3.0 and above, while using the ActionBar tabbed navigation style, the tabs sometimes appear above the action bar.
 * This helper method allows you to control the 'hasEmbeddedTabs' behaviour.
 * A value of true will put the tabs inside the ActionBar, a value of false will put it above or below the ActionBar.
 *
 * You should call this method while initialising your ActionBar tabs.
 * Don't forget to also call this method during orientation changes (in the onConfigurationChanged() method).
 *
 * @param inActionBar
 * @param inHasEmbeddedTabs
 */
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) {}
}
/**
*在Android 3.0及更高版本上,当使用ActionBar选项卡式导航样式时,选项卡有时会出现在操作栏上方。
*此帮助器方法允许您控制“hasEmbeddedTabs”行为。
*值为true将把标签放在操作栏内,值为false将把标签放在操作栏的上方或下方。
*
*您应该在初始化ActionBar选项卡时调用此方法。
*不要忘记在方向更改期间也调用此方法(在onConfigurationChanged()方法中)。
*
*@param不活动条
*@param inHasEmbeddedTabs
*/
公共静态void setHasEmbeddedTabs(对象不活动栏,AsEmbeddedTabs中的最终布尔值)
{
//获取ActionBar类
类actionBarClass=inActionBar.getClass();
//如果它是一个Jelly Bean实现(ActionBarImplJB),那么获取超级类(ActionBarImplICS)
if(“android.support.v7.app.ActionBarImplJB”.equals(actionBarClass.getName()))
{
actionBarClass=actionBarClass.getSuperclass();
}
尝试
{
//尝试获取mActionBar字段,因为当前ActionBar可能只是一个包装类
//如果失败,不用担心,这将是本机ActionBar类或ActionBarImplBase类的实例
最终字段actionBarField=actionBarClass.getDeclaredField(“mActionBar”);
actionBarField.setAccessible(true);
inActionBar=actionBarField.get(inActionBar);
actionBarClass=inActionBar.getClass();
}
捕获(非法访问例外){}
捕获(IllegalArgumentException e){}
catch(NoSuchFieldException){}
尝试
{
//现在调用setHasEmbeddedTabs方法,这将把选项卡放在ActionBar中
//如果失败了,你就只能靠自己了
最终方法Method=actionBarClass.getDeclaredMethod(“setHasEmbeddedTabs”,新类[]{Boolean.TYPE});
方法setAccessible(true);
调用(inActionBar,新对象[]{inHasEmbeddedTabs});
}
catch(NoSuchMethodException){}
catch(InvocationTargetException e){}
捕获(非法访问例外){}
捕获(IllegalArgumentException e){}
}

上述代码取自。

您是否找到了解决方案?我在使用appcompat时遇到了类似的问题,其中选项卡覆盖了HTC One X上的actionmode,希望sherlock解决方案可以帮助我找到appcompat解决方案。@ChrisM如果您仍然感兴趣并且没有找到解决方案,请查看我的答案。