Как установить активный элемент в раскрывающемся меню "Панель действий"?
Я пытаюсь исправить проблему с перезапуском активности при изменении ориентации.
У меня есть 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;
}
Я не уверен, что это лучшее решение.
Ответы
Ответ 1
Я только что нашел эту функцию. Это setSelectedNavigationItem(int position)
.
Установите выбранный пункт навигации в списке или в режиме навигации с вкладками.
Пример:
actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
actionBar.setListNavigationCallbacks(adapter, this);
actionBar.setSelectedNavigationItem(position);
Ответ 2
Как и в библиотеке поддержки 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());
}
Ответ 3
У меня также была одна и та же проблема. Сделав много исследований, я нашел решение здесь:
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();
}
}
Я надеюсь, что это тоже поможет кому-то другому.
Ответ 4
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 Bug сделал это для меня, код не указан:/
Ответ 5
Эта реализация работает для меня (измененная версия ответа @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) {
}
}