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.
- AndroidStudio - Dependencias de módulos en Gradle
- Android: SlidingMenu y ActionBarActivity
- ¿Cuál es la alternativa de SlidingDrawer que está obsoleta? Para deslizar hacia arriba desde abajo
- SlidingMenu y ViewPager con API13 (Honeycomb)
- 2 menú deslizante con diferentes tamaños
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 …
- 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
. - Ambos Fragments llaman
setHasOptionsMenu(true)
– He depurado a través de esto yonCreateOptionsMenu
se está llamando correctamente para cada uno. - Los iconos se muestran correctamente para ambos fragmentos – la animación no está ocurriendo cuando navego fuera del fragmento 'predeterminado'.
- 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
- Estoy usando
FragmentTransaction.remove()
yadd()
lugar dereplace()
como he tenido anteriormente problemas con back-button conreplace()
– Estoy usando la compatibilidad lib y he leído aquí que lareplace
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.
- ¿Cómo puedo hacer que el cajón de navegación no cierre completamente el cajón izquierdo?
- El menú deslizante de Android bloquea la interfaz de usuario
- ¿Cómo importar slidingmenu en Android Studio?
- La interfaz de usuario no se actualiza después de cambiar primero el menú deslizante en Android 5.0 lollipop
- ¿Cómo mostrar el DrawerLayout cuando se desliza de izquierda a derecha, no importa dónde?
- Mostrar un botón personalizado en ActionBarSherlock para mostrar un menú deslizante
- Desplazando el menú usando la biblioteca jfeinstein10
- Submenú para el menú deslizante en android
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();
- El polímero con Bower hace que la estructura falla en Córdoba
- ¿Es posible usar WebSockets o similar con una aplicación nativa de Android?