Как установить активный элемент в раскрывающемся меню «Панель действий»?

Я пытаюсь решить проблему с перезапуском активности при изменении ориентации.

У меня есть 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; } 

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

Solutions Collecting From Web of "Как установить активный элемент в раскрывающемся меню «Панель действий»?"

Я просто нашел эту функцию. Он setSelectedNavigationItem(int position) .

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

Пример:

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

Что касается библиотеки поддержки 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()); } 

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

http://mohitum.wordpress.com/tutorials/android/ -> под подсказкой 5.

Внесите OnPageChangeListener и в onPageSelected (int position) вызовите этот метод следующим образом:

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

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

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 toulouse@crunchyroll.com */ 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 Bug сделал это для меня, код не указан: /

Эта реализация работает для меня (измененная версия ответа @ 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) { } }