2011-01-08 34 views
23

Tengo dos actividades en la pila, para mostrarlas utilizo FLAG_ACTIVITY_REORDER_TO_FRONT. Hasta ahora todo bien, el problema viene cuando quiero traer la actividad con una animación usando overridePendingTransition.overridePendingTransition no funciona cuando FLAG_ACTIVITY_REORDER_TO_FRONT se usa

Intent i = new Intent(ActivityA.this, ActivityB.class); 
i.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); 
ActivityA.this.startActivity(i); 
overridePendingTransition(R.anim.transition_to_right, R.anim.transition_to_left); 

La transición no se muestra, sin embargo, si la bandera no se añade a la intención (la eliminación de la línea 2), entonces no hay ningún problema.

¿Es posible llevar una actividad al frente con una animación?

¡Muchas gracias!

Respuesta

0

¿Qué tal crear animaciones en onCreate() o onStart() de la segunda actividad.

+0

Hmm ... parece una buena idea! muchas gracias. Voy a aprender a manejar animaciones y probar eso. – Daniel

+0

@Daniel echa un vistazo a APIDemos (provisto junto con el marco de android) com.example.android.apis.animation.Rotation3dAnimation.java y cómo se usa en Transition3D.java. Debería darte una buena idea. – GSree

+0

¡Gracias a GSree por su ayuda! Intenté lanzar una animación deslizable en onPause() de la actividad A, y una presentación en el onResume() de la actividad B. Fue una buena idea, y funcionó, pero no es lo suficientemente suave , como se puede ver una especie de pestañeo negro, porque las animaciones no se ejecutan al mismo tiempo. Sigo trabajando en esto, si encuentro una buena solución, se lo haré saber. – Daniel

1

Mi colega se encontró con este problema y se las arregló para resolverlo al agregar el atributo mínimo de SDK (5 y más).

ya que esta característica estaba disponible desde api 5, haciendo cumplir el uso de un nivel más alto SDK hizo el truco para nosotros.

34

Me encontré con este mismo problema. El truco es anular la transición en la devolución de llamada onResume().

@Override 
public void onResume() { 
    super.onResume(); 
    overridePendingTransition(R.anim.transition_to_right, R.anim.transition_to_left); 
} 
+0

haciéndolo en onResume(). El efecto no es del todo fluido cuando la primera actividad aparece en la parte superior, aparece con un tirón – Ravi

+0

. Esto me funciona cuando comienzo una nueva actividad del servicio y necesito anular la transacción pendiente. – cwhsu

+2

Esta sugerencia no es correcta. onResume se llama en muchas ocasiones y no tiene nada que ver con el uso de una nueva intención. La solución correcta es la que señalé: hágalo en el método onNewIntent() –

31

En realidad la solución adecuada cuando se utiliza REORDER_TO_FRONT es llamar overridePendingTransition en el onNewIntent método() de la actividad que se va a abrir.

@Override 
protected void onNewIntent(Intent intent) { 
    super.onNewIntent(intent); 
    overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); 
} 

reemplazar con sus transiciones.

Si es necesario sustituir selectivamente la transición se puede añadir un extra en su intento y comprobar que en el onNewIntent() para decidir qué hacer.

Esto no es conveniente si usted no sabe la transición que se abrirá (si no se especifica explícitamente por ejemplo) pero por lo demás es la solución correcta.

+6

La única solución adecuada. Debería ser aceptada la respuesta. – tomrozb

+0

Desearía saber por qué algunas personas rechazaron mi respuesta, esto es, como dijo tomrozb, la única solución adecuada –

-2

he hecho algo similar y lo hice de la siguiente manera:

private Stack<String> stack; 
ViewAnimator mViewAnimator; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mViewAnimator = new ViewAnimator(this); 
    if (stack == null) stack = new Stack<String>(); 
    push("FirstStackActivity", new Intent(this, FirstStackActivity.class)); 
} 

@Override 
public void finishFromChild(Activity child) { 
    pop(); 
} 

@Override 
public void onBackPressed() { 
    pop(); 
} 

public void push(String id, Intent intent) { 
    Window window = getLocalActivityManager().startActivity(id, intent); 
    if (window != null) { 
     stack.push(id); 
     View view = window.getDecorView(); 
     mViewAnimator.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in)); 
     mViewAnimator.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out));    
     mViewAnimator.addView(view); 
     mViewAnimator.showNext(); 
     setContentView(mViewAnimator); 
    } 
} 

public void pop() { 
    if (stack.size() == 1) finish(); 
    if (stack.size() > 0) { 
     LocalActivityManager manager = getLocalActivityManager(); 
     Intent lastIntent = manager.getActivity(stack.peek()).getIntent(); 
     Window newWindow = manager.startActivity(stack.peek(), lastIntent); 
     View view = newWindow.getDecorView(); 
     mViewAnimator.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_in)); 
     mViewAnimator.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_out)); 
     mViewAnimator.showPrevious(); 
     mViewAnimator.removeView(view); 
    } 
    destroy(stack.pop()); 
} 


/** 
* BugFix official 
* @param id 
* @return 
*/ 
public boolean destroy(String id) { 
    final LocalActivityManager activityManager = getLocalActivityManager(); 
    if (activityManager != null) { 
     activityManager.destroyActivity(id, false); 
     try { 
      final Field mActivitiesField = LocalActivityManager.class.getDeclaredField("mActivities"); 
      if (mActivitiesField != null) { 
       mActivitiesField.setAccessible(true); 
       @SuppressWarnings("unchecked") 
       final Map<String, Object> mActivities = (Map<String, Object>) mActivitiesField.get(activityManager); 
       if (mActivities != null) { 
        mActivities.remove(id); 
       } 
       final Field mActivityArrayField = LocalActivityManager.class.getDeclaredField("mActivityArray"); 
       if (mActivityArrayField != null) { 
        mActivityArrayField.setAccessible(true); 
        @SuppressWarnings("unchecked") 
        final ArrayList<Object> mActivityArray = (ArrayList<Object>) mActivityArrayField.get(activityManager); 
        if (mActivityArray != null) { 
         for (Object record : mActivityArray) { 
          final Field idField = record.getClass().getDeclaredField("id"); 
          if (idField != null) { 
           idField.setAccessible(true); 
           final String _id = (String) idField.get(record); 
           if (id.equals(_id)) { 
            mActivityArray.remove(record); 
            break; 
           } 
          } 
         } 
        } 
       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return true; 
    } 
    return false; 
} 
2

Calling

overridePendingTransition(R.anim.transition_to_right, R.anim.transition_to_left); 

después de acabado(); de la actividad de cierre funcionó para mí.

finish(); 
overridePendingTransition(R.anim.transition_to_right, R.anim.transition_to_left); 

Es mejor que llamar onResume, ya que hace que la actividad más independiente sobre los ingreso y egreso de animaciones:


de llamada después de terminar la actividad del remitente:

Actividad A --- Enter Transición 1 (en A) ---> Actividad B --- Ingresar Transición 2 (en B) ---> Actividad C

Actividad A < --- Salida Transición 1 (en B) --- Actividad B < --- Salida Transición 2 (en C) --- Actividad C

Actividad A --- Ingrese Transición 1 (en A) ---> Actividad C --- Ingrese Transición 3 (en C) - -> Actividad B

Actividad a < --- Exit Transición 3 (en C) --- Actividad C < --- Exit Transición 2 (en B) --- Actividad B



Llamar onResume de la actividad del receptor:

Actividad A --- Ingrese la Transición 1 (en B) ---> Activ ity B --- Ingresar Transición 2 (en C) ---> Actividad C

Actividad A < --- Ingresar Transición 1 (en A) --- Actividad B < --- Ingresar Transición 2 (en B) --- Actividad C

Actividad a --- Introduzca Transición 3 (en C) ---> Actividad C --- Introduzca Transición 2 (en B) ---> Actividad B

Actividad a < --- Ingresar Transición 1 (en A) --- Actividad C < --- Ingresar Transición 3 (en C) --- Actividad B

Aquí la animación onResume siempre tiene que ser la misma sin importar qué actividad del remitente es, en cambio, el primer enfoque, donde puede personalizar la animación fácilmente.

2

para mí, la solución fue la de asegurarse de que está corriendo en el hilo de interfaz de usuario

runOnUiThread(new Runnable() { 
      public void run() { 
       startActivity(new Intent(ActivityOne.this, ActivityTwo.class)); 
       overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); 
      } 
     }); 

     finish(); 
+0

en mi caso, ese fue exactamente mi error –

1

Tengo el mismo problema. Te sugiero que revises tu AndroidManifest.xml para asegurarte de que ActivityA y ActivityB no tienen ningún conjunto Theme.Translucent.NoTitleBar, este tema contiene "android: windowIsTranslucent" = true, causa el problema.

Espero que esto te ayude.

Cuestiones relacionadas