J'essaie de résoudre le problème du redémarrage de l'activité sur les changements d'orientation.
J'ai un ActionBar
avec navigation dans la liste déroulante et après chaque rotation, le premier élément de cette liste est activé. Garder le contenu de fragment
n'a pas été difficile, mais je ne sais pas comment définir l'élément de liste actif.
Voici la définition de 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);
Et voici ma solution:
@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;
}
Je ne suis pas sûr que ce soit la meilleure solution.
Je viens de trouver cette fonction. C'est setSelectedNavigationItem(int position)
.
Définissez l'élément de navigation sélectionné dans les modes de navigation par liste ou par onglets.
Exemple:
actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
actionBar.setListNavigationCallbacks(adapter, this);
actionBar.setSelectedNavigationItem(position);
Depuis la bibliothèque de support v7, il vous suffit de sauvegarder/restaurer l'état de l'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());
}
@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();
}
}
ce hack autour du bug officiel Android l'a fait pour moi, le codenippet ci-dessus n'a pas: /
Cette implémentation fonctionne pour moi (une version modifiée de la réponse de @ 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) {
}
}
Je rencontrais également le même problème. En faisant beaucoup de recherches, j'ai trouvé la solution ici:
http://mohitum.wordpress.com/tutorials/Android/ -> sous Astuce 5.
Implémentez OnPageChangeListener et dans onPageSelected (int position) appelez cette méthode comme ceci:
@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();
}
}
J'espère que cela peut aussi aider quelqu'un d'autre.