Android – problemas para animar el icono de ActionBar de Fragments

Tengo algunos problemas consistentemente animando un icono de "actualización" en el ActionBar de mi aplicación.

Tengo un contenedor FragmentActivity que intercambia fragmentos dentro y fuera cuando el usuario navega a través de la aplicación (ya sea dentro del propio fragmento o desde una opción de SlidingMenu). Así que cuando la aplicación se carga por primera vez, mi FragmentContainer agrega FragA. Desde FragA el usuario puede navegar a FragB, que luego se intercambia.

En la barra de acción se muestra un icono de 'actualización' estático. A medida que se carga cada fragmento, reemplazo esto con un icono de "spinner" animado. Cuando la carga se completa, vuelvo al icono de actualización original.

El problema es que esta animación sólo funciona para el fragmento original (FragA, en este caso). Cuando el usuario navega a FragB y selecciona el icono de actualización, la actualización se activa, pero la animación nunca sucede. De manera similar, si se pulsa el botón de retroceso para volver a FragA, esto sigue ahora el mismo patrón, es decir, el botón de actualización no se anima cuando se pulsa.

Cosas a tener en cuenta …

  1. Estoy usando ActionBarSherlock y la implementación de SlidingMenu en https://github.com/jfeinstein10/SlidingMenu . Así que la actividad anterior es en realidad una SlidingFragmentActivity .
  2. Ambos Fragments llaman setHasOptionsMenu(true) – He depurado a través de esto y onCreateOptionsMenu se está llamando correctamente para cada uno.
  3. Los iconos se muestran correctamente para ambos fragmentos – la animación no está ocurriendo cuando navego fuera del fragmento 'predeterminado'.
  4. Veo el mismo comportamiento al usar el SlidingMenu para navegar – Cargas FragA, obras de animación -> SlidingMenu se utiliza para navegar a un fragmento diferente … la animación no funciona -> Atrás el botón de FragA … la animación no funciona Aquí tampoco
  5. Estoy usando FragmentTransaction.remove() y add() lugar de replace() como he tenido anteriormente problemas con back-button con replace() – Estoy usando la compatibilidad lib y he leído aquí que la replace aplicación es un poco Buggy – y no usarlo sin duda arreglaron los problemas que estaba viendo.

Ejemplos de código a continuación:

Mi código para cargar el fragmento original es ….

 FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.add(R.id.content_frame, new FragA()); ft.addToBackStack(null); ft.commit(); 

Para 'intercambiar' FragB por FragA ….

 public void switchContent(PysoBaseFragment fragment) { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.remove(existingFragment); ft.add(R.id.content_frame, fragment); ft.addToBackStack(null); ft.commit(); } 

Este método se declara en la actividad del contenedor y se llama desde FragA es decir …

 getFragmentContainer().switchContent(new FragB()); 

El código para girar el icono se llama desde el nuevo Fragmento a medida que empieza a cargarse. Es algo así como …

  ImageView spinnerActionView = (ImageView) inflater.inflate(R.layout.refresh_action_view, null); Animation rotation = AnimationUtils.loadAnimation(this, R.anim.rotate_animation); rotation.setRepeatCount(Animation.INFINITE); spinnerActionView.startAnimation(rotation); menuItemRefresh = menu.findItem(R.id.menu_refresh); menuItemRefresh.setActionView(spinnerActionView); 

Donde menu está asignado a una variable de instancia del contenedor cuando onCreateOptionsMenu se llama.

Actualizar:

He notado otro insecto extraño en esta área (me complace añadir esto como una pregunta aparte, pero lo estoy actualizando aquí con la esperanza de que arrojará algo de luz sobre mi problema original – creo que ambos son causados ​​por Cómo he configurado mi barra de acción de mis Fragmentos).

Cuando cargue un fragmento por primera vez, se mostrará 1 icono de actualización estática. Si giro la pantalla … aparece otro icono de actualización … cuando vuelvo a girar la pantalla, aparece un icono de la tercera actualización!

Aún más extraño, al hacer clic en el botón de retroceso se eliminan cada icono adicional a su vez, antes de finalmente (en el 4º clic) volver a la pantalla anterior.

Nunca cambie los elementos del menú en algún lugar excepto

 onPrepareOtionsMenu(){ } 

Usted debe algo como esto.

En su actividad:

 boolean mIsRefreshing =false; public boolean onPrepareOptionsMenu(Menu menu) { if(mIsRefreshing){ final MenuItem menuItemRefresh = menu.findItem(R.id.menu_refresh); menuItemRefresh.setActionView(spinnerActionView); } return true; } public void setRefreshing(boolean refreshing){ mIsRefreshing = refreshing; invalidateOptionsMenu(); //supportInvelidateOptionsMenu() } 

Así que ahora puedes llamar desde tu frament

 ((YourActivity)getActivity()).setRefreshing(true); ((YourActivity)getActivity()).setRefreshing(false); 

Si está utilizando el mismo objeto de animación cada vez, puede que tenga que restablecer la animación antes de intentar ejecutarla de nuevo.

Trate de añadir rotation.reset () encima de su llamada a startAnimation ().

  "I've noticed another weird bug in this area (I'm happy to add this as a separate question, but I'm updating it here in the hope that it will shed some light on my original problem - I believe both are caused by how I have configured my action-bar from my Fragments). When I first load a fragment I have 1 static refresh icon displayed. If I rotate the screen... another refresh icon appears... when I rotate the screen back, a 3rd refresh icon appears! Stranger still, clicking the back-button removes each additional icon in turn, before finally (on the 4th click) returning to the previous screen." 

Puedo dar Explicación a esto, Cuando cambias orientación (Potrait <-> paisaje).

Una actividad se reinicia cuando cambia la orientación. Supongo que su código no está guardando la información necesaria antes de que comience el reinicio. Puede detener este comportamiento predeterminado manipulando cambios de configuración específicos (es decir: cambio de orientación). Un buen tutorial sobre cómo hacerlo se encuentra aquí: Manejo de cambios en tiempo de ejecución

Está agregando una vista de acción para agregar la animación. Si intenta hacer algo más, como cambiar el ícono del elemento de menú (incluso si no está animado, sólo para ver si cambia) en su lugar, ¿funciona?

Sólo llama a onCreateOptionsMenu () en la actividad principal (quiero decir Sliding fragment activity) .No necesito llamar a onCreateOptionsMenu () de cada fragmento. Estoy dando un fragmento de muestra a continuación.

 Call from fragment (whenerver loading starts and end) yourSlidingFragmnetActivity.refresh = true/false; (u can have this logic of your own) getActivity().supportInvalidateOptionsMenu(); @Override public boolean onCreateOptionsMenu(Menu menu) { menu.add(BaseListActivity.DEFAULT_GROUP_ID, BaseListActivity.MENU_ITEM_RELOAD_LIST, BaseListActivity.DEFAULT_ORDER, "Refresh").setIcon(R.drawable.ic_menu_refresh_new) .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == BaseListActivity.MENU_ITEM_RELOAD_LIST) { item.setActionView(R.layout.progressbar_layout); item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); return true; } return true; } public static boolean refresh = false; @Override public boolean onPrepareOptionsMenu(Menu menu) { MenuItem item = menu.getItem(0); if (refresh) { item.setActionView(R.layout.progressbar_layout); } else { item.setIcon(R.drawable.ic_menu_refresh_new); } return true; } R.layout.progressbar_layout: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:addStatesFromChildren="true" android:focusable="true" android:paddingLeft="4dp" android:paddingRight="4dp" android:gravity="center" style="?attr/actionButtonStyle"> <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusable="true" style="@android:style/Widget.ProgressBar.Small"/> </LinearLayout> 

También estoy usando jfeinstein10 slidingmenu lib, no estoy agregando o quitando fragmentos, siempre estoy reemplazarlos y en menthod oncreate iam usando como este

 private Fragment mContent; if(mContent == null){ mContent = new SampleFragment(); } // set the Above View setContentView(R.layout.content_frame); getSupportFragmentManager() .beginTransaction() .replace(R.id.content_frame,mContent) .commit(); 
  • Cómo mostrar SlidingPaneLayout en el lado derecho
  • Adición de una imagen grande a un cajón de navegación (SlidingMenu libs) - ¿Cómo?
  • Cómo importar slidingmenu en Intellij Idea?
  • ¿Cómo abrir el menú deslizante en el evento de clic del botón?
  • ¿Qué es crittercism_v3_0_3_sdkonly utilizado en jfeinstein10 / SlidingMenu?
  • Android: menú deslizante con submenú
  • Imitando el cajón de navegación de la aplicación youtube / gmail
  • Cajón de navegación coexistente y diseño de panel deslizante
  • Cambiar a una nueva actividad, en lugar de cambiar fragmentos, cuando se hace clic en el elemento de lista de deslizamiento de jfeinstein10
  • Instalación de la biblioteca Android SlidingMenu
  • Problemas con la integración de SlidingMenu
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.