2013-10-28 90 views
2

我有一個ActionBarSherlock的奇怪問題,使用標籤導航和一個動作模式。ActionBarSherlock重疊的標籤導航和ActionMode

重複的問題很簡單,我用演示代碼生成下面的例子活動:

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 

     } 

    } 

} 

它正常工作在Android 4.0(真實設備和仿真測試),但果凍豆(只測試在模擬器上)我有以下行爲。

  • 應用程序開始(肖像模式),它工作正常;
  • 我旋轉應用程序,它工作正常;
  • 我再次旋轉應用程序,現在標籤導航和ActionMode重疊(http://i.stack.imgur.com/Zf1VG.png)。

有時(但很少),一切都很完美,特別是如果我在Dev中啓用了所有動畫。設置(通常我禁用所有動畫)。

我正在使用ActionBarSherlock 4.4。

任何建議將不勝感激,因爲我真的不明白我犯了什麼錯誤。

感謝和問候。

+0

你有沒有找到解決辦法呢?我遇到類似的問題,使用appcompat標籤覆蓋HTC One X上的操作模式,希望sherlock解決方案能夠幫助我追蹤appcompat解決方案。 – GrouchyPanda

+0

@ChrisM如果你仍然感興趣,但沒有找到解決方案,請看我的答案。 – Leri

回答

1

我最近遇到同樣的問題。浪費了幾天的時間後,發現這種奇怪的行爲是由this issue中描述的UX缺陷造成的,實際上與ABS (action bar sherlock)無關。

最可靠的解決辦法似乎是使用反射來控制操作欄應該如何呈現:

/** 
* 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) {} 
} 

上面的代碼從this blog post拍攝。