2012-01-27 27 views
41

Estoy tratando de solucionar el problema con el reinicio de la actividad en los cambios de orientación.¿Cómo establecer el elemento activo en la barra de navegación desplegable de la barra de acciones?

Tengo un ActionBar con la lista desplegable de navegación y después de cada rotación se activa el primer elemento de esta lista. Mantener el contenido de fragment no fue difícil, pero no sé cómo configurar el elemento de la lista activa.

Aquí es la definición 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); 

Y aquí está mi solución:

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

No estoy seguro de que es la mejor solución sin embargo.

Respuesta

83

Acabo de encontrar esa función. Es setSelectedNavigationItem(int position).

ajusta el elemento de navegación seleccionada en la lista o modos de navegación con pestañas.

Ejemplo:

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

¿Le importaría publicar un ejemplo de cómo llegó esto funcione? He estado intentando algo como getActionBar(). SetSelectedNavigationItem (1) pero no tiene ningún efecto ... (Alguien más con el mismo problema aquí: http://stackoverflow.com/questions/8487425/actionbar-dropdown-spinner-item -defaults-to-first-item) – brk3

+1

Claro, actualicé mi respuesta. Además, puedes echarle un vistazo al código fuente de mi aplicación para ver cómo la uso. https://github.com/Tsukanov/Simple-Counter/blob/master/src/me/tsukanov/counter/CounterActivity.java#L90 – Roman

+0

¡Gracias, funciona! Creo que lo que debía haber estado haciendo mal fue llamar al setSelectedNavigationItem antes de agregar el adaptador.Estaba seguro de que lo intenté de esa manera antes, pero bueno, ahora funciona :) – brk3

0

I también estaba experimentando el mismo problema. Haciendo un gran trabajo de investigación he encontrado la solución aquí:

http://mohitum.wordpress.com/tutorials/android/ -> debajo de la punta 5.

Implementar OnPageChangeListener y en el onPageSelected (posición int) llama a este método como este:

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

Espero que esto también pueda ayudar a alguien más.

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

este corte alrededor del insecto androide oficial lo hizo por mí, la codesnippet anterior no lo hizo:/

1

A partir del soporte de la biblioteca v7, sólo tiene para guardar/restaurar el estado de la Barra de acciones:

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

Esta aplicación funciona para mí (una versión modificada de la respuesta 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) { 
    } 
} 
Cuestiones relacionadas