2012-01-27 4 views
41

Я пытаюсь решить проблему с перезапуском активности при изменении ориентации.Как установить активный элемент в раскрывающемся меню панели действий?

У меня есть ActionBar с раскрывающимся списком навигации и после каждого поворота активируется первый элемент этого списка. Содержание fragment было не сложно, но я не знаю, как установить активный элемент списка.

Вот определение ActionBar:

getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); 
ArrayAdapter<CharSequence> list = ArrayAdapter 
    .createFromResource(this, R.array.action_list, android.R.layout.simple_dropdown_item_1line); 
list.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
getActionBar().setListNavigationCallbacks(list, this); 

А вот мой обходной путь:

@Override 
public boolean onNavigationItemSelected(int itemPosition, long itemId) { 
    if (!application.isRotated) { 
     application.activePosition = itemPosition; 
     application.activeId = itemId; 
     getFragmentManager().beginTransaction() 
      .replace(android.R.id.content, MyFragment.newInstance(itemPosition)) 
      .commit(); 
    } else { 
     application.isRotated = false; 
     this.onNavigationItemSelected(application.activePosition, application.activeId);    
    } 
    return true; 
} 

@Override 
protected void onStop() { 
    super.onStop(); 
    application.isRotated = true; 
} 

Я не уверен, что это лучшее решение, хотя.

ответ

83

Я только что нашел, что функция. Это setSelectedNavigationItem(int position).

Установить выбранный пункт навигации в списке или в режиме навигации с вкладками.

Пример:

actionBar = getActionBar(); 
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); 
actionBar.setListNavigationCallbacks(adapter, this); 
actionBar.setSelectedNavigationItem(position); 
+1

Не могли бы вы размещая пример того, как вы получили эту работу? Я пытаюсь что-то вроде getActionBar(). SetSelectedNavigationItem (1), но он не имеет никакого эффекта. (Кто-то другой с той же проблемой здесь: http://stackoverflow.com/questions/8487425/actionbar-dropdown-spinner-item -defaults-to-first-item) – brk3

+1

Конечно, обновил мой ответ. Кроме того, вы можете посмотреть исходный код моего приложения, чтобы узнать, как я его использую. https://github.com/Tsukanov/Simple-Counter/blob/master/src/me/tsukanov/counter/CounterActivity.java#L90 – Roman

+0

Спасибо, это работает! Я предполагаю, что я, должно быть, делал неправильно, вызывал setSelectedNavigationItem перед добавлением адаптера.Был уверен, что я пробовал это так раньше, но хорошо, работает сейчас :) – brk3

0

Я также испытывают те же проблемы. Создание много исследований, я нашел решение здесь:

http://mohitum.wordpress.com/tutorials/android/ -> под Tip 5.

Реализовать OnPageChangeListener и в onPageSelected (INT позиция) этот метод вызывается так:

@Override 
public void onPageSelected(int position) { 
    mActionBar.setSelectedNavigationItem(position); 
    selectInSpinnerIfPresent(position, true); 
} 
private void selectInSpinnerIfPresent(int position, boolean animate) { 
    try { 
    ActionBar actionBarView = mActionBar; 
    Class<?> actionBarViewClass = actionBarView.getClass(); 
    Field mTabScrollViewField = actionBarViewClass.getDeclaredField(“mTabScrollView”); 
    mTabScrollViewField.setAccessible(true); 
    Object mTabScrollView = mTabScrollViewField.get(actionBarView); 
    if (mTabScrollView == null) { 
     return; 
    } 
    Field mTabSpinnerField = mTabScrollView.getClass().getDeclaredField(“mTabSpinner”); 
    mTabSpinnerField.setAccessible(true); 
    Object mTabSpinner = mTabSpinnerField.get(mTabScrollView); 
    if (mTabSpinner == null) { 
     return; 
    } 
    Method setSelectionMethod = mTabSpinner.getClass().getSuperclass().getDeclaredMethod(“setSelection”, Integer.TYPE, Boolean.TYPE); 
    setSelectionMethod.invoke(mTabSpinner, position, animate); 
    Method requestLayoutMethod = mTabSpinner.getClass().getSuperclass().getDeclaredMethod(“requestLayout”); 
    requestLayoutMethod.invoke(mTabSpinner); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 

Надеюсь, это тоже поможет кому-то другому.

0

Codesnippet on Gist


@Override 
public void onPageScrollStateChanged(int state) { 
} 


@Override 
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
} 


@Override 
public void onPageSelected(int position) { 
    actionBar.setSelectedNavigationItem(position); 

    selectInSpinnerIfPresent(position, true); 
} 


/** 
* Hack that takes advantage of interface parity between ActionBarSherlock and the native interface to reach inside 
* the classes to manually select the appropriate tab spinner position if the overflow tab spinner is showing. 
* 
* Related issues: https://github.com/JakeWharton/ActionBarSherlock/issues/240 and 
* https://android-review.googlesource.com/#/c/32492/ 
* 
* @author [email protected] 
*/ 
private void selectInSpinnerIfPresent(int position, boolean animate) { 
    try { 
     View actionBarView = findViewById(R.id.abs__action_bar); 
     if (actionBarView == null) { 
      int id = getResources().getIdentifier("action_bar", "id", "android"); 
      actionBarView = findViewById(id); 
     } 

     Class<?> actionBarViewClass = actionBarView.getClass(); 
     Field mTabScrollViewField = actionBarViewClass.getDeclaredField("mTabScrollView"); 
     mTabScrollViewField.setAccessible(true); 

     Object mTabScrollView = mTabScrollViewField.get(actionBarView); 
     if (mTabScrollView == null) { 
      return; 
     } 

     Field mTabSpinnerField = mTabScrollView.getClass().getDeclaredField("mTabSpinner"); 
     mTabSpinnerField.setAccessible(true); 

     Object mTabSpinner = mTabSpinnerField.get(mTabScrollView); 
     if (mTabSpinner == null) { 
      return; 
     } 

     Method setSelectionMethod = mTabSpinner.getClass().getSuperclass().getDeclaredMethod("setSelection", Integer.TYPE, Boolean.TYPE); 
     setSelectionMethod.invoke(mTabSpinner, position, animate); 

     Method requestLayoutMethod = mTabSpinner.getClass().getSuperclass().getDeclaredMethod("requestLayout"); 
     requestLayoutMethod.invoke(mTabSpinner); 
    } catch (IllegalArgumentException e) { 
     e.printStackTrace(); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch (NoSuchFieldException e) { 
     e.printStackTrace(); 
    } catch (NoSuchMethodException e) { 
     e.printStackTrace(); 
    } catch (InvocationTargetException e) { 
     e.printStackTrace(); 
    } 
} 

этот хак вокруг официального Буг Android сделал это для меня, codesnippet выше, не сделал:/

1

С поддержкой библиотеки v7, вам просто нужно для сохранения/восстановления состояния ActionBar:

private static final String STATE_SELECTED_NAVIGATION_ITEM = "selectedNavItem"; 

@Override 
public void onRestoreInstanceState(Bundle savedInstanceState) { 
    // Restore the previously serialized current dropdown position. 
    if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) { 
     getSupportActionBar().setSelectedNavigationItem(
       savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM)); 
    } 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    // Serialize the current dropdown position. 
    outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getSupportActionBar() 
      .getSelectedNavigationIndex()); 
} 
0

Эта реализация работает для меня (модифицированная версия @ mohitum007 Ответные):

public static void selectInSpinnerIfPresent(Object inActionBar, 
     int position, boolean animate) { 
    // 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 { 
     Field mTabScrollViewField = actionBarClass 
       .getDeclaredField("mTabScrollView"); 
     mTabScrollViewField.setAccessible(true); 
     Object mTabScrollView = mTabScrollViewField.get(inActionBar); 
     if (mTabScrollView == null) { 
      return; 
     } 
     Field mTabSpinnerField = mTabScrollView.getClass() 
       .getDeclaredField("mTabSpinner"); 
     mTabSpinnerField.setAccessible(true); 
     Object mTabSpinner = mTabSpinnerField.get(mTabScrollView); 
     if (mTabSpinner == null) { 
      return; 
     } 
     Method setSelectionMethod = mTabSpinner 
       .getClass() 
       .getSuperclass() 
       .getDeclaredMethod("setSelection", Integer.TYPE, 
         Boolean.TYPE); 
     setSelectionMethod.invoke(mTabSpinner, position, animate); 
     Method requestLayoutMethod = mTabSpinner.getClass().getSuperclass() 
       .getDeclaredMethod("requestLayout"); 
     requestLayoutMethod.invoke(mTabSpinner); 
    } catch (NoSuchMethodException | InvocationTargetException 
      | IllegalAccessException | IllegalArgumentException | NoSuchFieldException e) { 
    } 
} 
Смежные вопросы