¿Cómo puedo volver a una actividad para padres correctamente?


Tengo 2 actividades (A y B) en mi aplicación Android y uso una intent para pasar de la actividad A a la actividad B. El uso de parent_activity está habilitado:

 <activity
        android:name=".B"
        android:label="B" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.app_name.A" />
  </activity>

También uso un tema que proporciona un botón HACIA ARRIBA.

Así que después de llamar a la actividad B puedo usar el botón de ARRIBA para volver a la actividad A. El problema es que la aplicación parece llamar a la onCreate()-función de la actividad A de nuevo y este no es el comportamiento que necesito. Necesito actividad A para mirar el de la misma manera que se veía antes de llamar a la actividad B.

¿Hay alguna manera de lograr esto?

Gracias de antemano

EDITAR:

No escribí ningún código para iniciar la actividad B desde la actividad A. Creo que eclipse la genera automáticamente.

La clase B se parece a:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_b, menu);
    return true;
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
    }
    return super.onOptionsItemSelected(item);
}
Author: ashiaka, 2012-09-05

16 answers

Declaraste la actividad A con el estándar launchMode en el manifiesto de Android. De acuerdo con la documentación , eso significa lo siguiente:

El sistema siempre crea una nueva instancia de la actividad en el destino tarea y dirige la intención a ella.

Por lo tanto, el sistema se ve obligado a recrear la actividad A (es decir, llamar a onCreate) incluso si la pila de tareas se maneja correctamente.

Para solucionar este problema es necesario cambiar el manifiesto, añadiendo lo siguiente atributo a la declaración de actividad A:

android:launchMode="singleTop"

Nota: llamar a finish() (como se sugirió como solución antes) funciona solo cuando está completamente seguro de que la instancia de la actividad B que está terminando vive encima de una instancia de la actividad A. En flujos de trabajo más complejos (por ejemplo, iniciar la actividad B desde una notificación) este podría no ser el caso y debe iniciar correctamente la actividad A desde B.

 310
Author: LorenzCK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-26 13:45:59

Respuesta actualizada: Subir Diseño de navegación

Debe declarar qué actividad es la padre apropiada para cada actividad. Al hacerlo, el sistema puede facilitar patrones de navegación como Up porque el sistema puede determinar la actividad padre lógica del archivo de manifiesto.

Así que para eso tienes que declarar tu actividad padre en la etiqueta Actividad con atributo

android:parentActivityName

Como,

<!-- The main/home activity (it has no parent activity) -->
    <activity
        android:name="com.example.app_name.A" ...>
        ...
    </activity>
    <!-- A child of the main activity -->
    <activity
        android:name=".B"
        android:label="B"
        android:parentActivityName="com.example.app_name.A" >
        <!-- Parent activity meta-data to support 4.0 and lower -->
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.app_name.A" />
    </activity>

Con la actividad principal declarada de esta manera, puede navegar hasta el padre apropiado como a continuación,

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // Respond to the action bar's Up/Home button
    case android.R.id.home:
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

Así que Cuando llamas a NavUtils.navigateUpFromSameTask(this); este método, finaliza la actividad actual e inicia (o reanuda) la actividad padre apropiada. Si la actividad principal de destino está en la pila posterior de la tarea, se adelanta como se define en FLAG_ACTIVITY_CLEAR_TOP.

Y para mostrar el botón Arriba tienes que declarar setDisplayHomeAsUpEnabled():

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

Respuesta Antigua: (Sin Navegación Arriba, Navegación Atrás predeterminada)

Sucede solo si está comenzando la Actividad A de nuevo desde la Actividad B.

Usando startActivity().

En lugar de esto desde la Actividad A inicie la Actividad B usando startActivityForResult() y anule onActivtyResult() en la actividad A.

Ahora en la Actividad B, simplemente llame a finish() on botón Arriba. Así que ahora dirigiste a la Actividad A onActivityResult() sin crear la Actividad A de nuevo..

 72
Author: user370305,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-26 07:36:27

Tenía más o menos la misma configuración que conduce al mismo comportamiento no deseado. Para mí esto funcionó: agregar el siguiente atributo a una actividad A en el Manifest.xml de mi aplicación:

android:launchMode="singleTask"

Ver este artículo para más explicación.

 22
Author: androidnewbie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-14 22:24:06

Aunque es una pregunta antigua, aquí hay otra (en mi humilde opinión, la solución más limpia y mejor), ya que todas las respuestas anteriores no funcionaron para mí desde que vinculé profundamente la actividad B desde un Widget .

public void navigateUp() {
final Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot()) {
    Log.v(logTag, "Recreate back stack");
        TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities();
  } else {
    NavUtils.navigateUpTo(this, upIntent);
  }
}

[https://stackoverflow.com/a/31350642/570168 ]

Pero también ver: https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-android

 15
Author: Lord Flash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:26

Una mejor manera de lograr esto es mediante el uso de dos cosas: llamada:

NavUtils.navigateUpFromSameTask(this);

Ahora, para que esto funcione, necesita que su archivo de manifiesto indique que la actividad A tiene una actividad principal B. La actividad principal no necesita nada. En la versión 4 y superior obtendrá una buena flecha hacia atrás sin esfuerzo adicional (esto se puede hacer en versiones inferiores también con un poco de código, lo pondré a continuación) Puede establecer estos datos en la pestaña manifest->application en la GUI (desplácese hacia abajo hasta el padre nombre de la actividad, y ponerlo a mano)

Nodo de soporte:

Si desea admitir la versión por debajo de la versión 4, también debe incluir metadatos. haga clic derecho en la actividad, add->meta data, name =android.apoyo.PARENT_ACTIVITY y value = your.full.activity.name

Para obtener la flecha de niza también en versiones inferiores:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

Tenga en cuenta que necesitará la versión 7 de la biblioteca de soporte para que todo esto funcione, ¡pero vale la pena!

 7
Author: donald,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-22 14:55:54

Lo intenté android:launchMode="singleTask", pero no ayudó. Me funcionó usando android:launchMode="singleInstance"

 4
Author: Pnemonic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-04 08:20:04

Añadiendo a la respuesta de @LorenCK, cambiar

NavUtils.navigateUpFromSameTask(this);

Al siguiente código si su actividad se puede iniciar desde otra actividad y esto puede convertirse en parte de la tarea iniciada por alguna otra aplicación

Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
    TaskStackBuilder.create(this)
            .addNextIntentWithParentStack(upIntent)
            .startActivities();
} else {
    NavUtils.navigateUpTo(this, upIntent);
}

Esto iniciará una nueva tarea e iniciará la Actividad principal de su Actividad que puede definir en el Manifiesto como se muestra a continuación de Min SDK version

<meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.example.app_name.A" />

O usando parentActivityName si es > 15

 4
Author: Sourabh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-22 19:13:57

Lo que funcionó para mí fue agregar:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case android.R.id.home:
                onBackPressed();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

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

A TheRelevantActivity.java y ahora está funcionando como se esperaba

Y sí, no olvides agregar:

getSupportActionbar.setDisplayHomeAsUpEnabled(true); en el método onCreate()

 4
Author: Hammad Nasir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-28 10:45:54

Tuve un problema similar al usar Android 5.0 con un mal nombre de actividad de los padres

<activity
        android:name=".DisplayMessageActivity"
        android:label="@string/title_activity_display_message"
        android:parentActivityName=".MainActivity" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myfirstapp.MainActivity" />
    </activity>

Eliminé el com.ejemplo.myfirstapp desde el nombre de la actividad principal y funcionó correctamente

 3
Author: Patrick Bergthold,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-29 16:35:09

Agregue a su actividad información de manifiesto con el atributo

android:launchMode="singleTask"

Está funcionando bien para mí

 2
Author: Pravesh Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-08 06:32:29

En la clase Java: -

    toolbar = (Toolbar) findViewById(R.id.apptool_bar);
    setSupportActionBar(toolbar);

    getSupportActionBar().setTitle("Snapdeal");

    getSupportActionBar().setHomeButtonEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

En Manifiesto: -

<activity
            android:name=".SubActivity"
            android:label="@string/title_activity_sub"
            android:theme="@style/AppTheme" >
            <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity"></meta-data>
    </activity>

Te ayudará

 2
Author: Kasthuri Shravankumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-28 07:39:41

Prueba esto:

Intent intent;
@Override
public void onCreate(Bundle savedInstanceState) {
intent = getIntent();   
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
getActionBar().setDisplayHomeAsUpEnabled(true);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_b, menu);
return true;
}  


@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
    case android.R.id.home:
    NavUtils.navigateUpTo(this,intent);
        return true;
}
return super.onOptionsItemSelected(item);
}
 1
Author: Luis Valadez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-29 05:43:05
    @Override
public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
    case android.R.id.home:
        finish();
        return true;
}
return super.onOptionsItemSelected(item);

Como una pulsación hacia atrás

 1
Author: Dan Alboteanu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-05 10:54:15

Entrar en mi manifiesto y agregar android:launchMode="singleTop" a la actividad hizo el truco para mí.

Esto resolvió específicamente mi problema porque no quería que Android creara una nueva instancia de la actividad anterior después de presionar el botón Up en la barra de herramientas; en su lugar, quería usar la instancia existente de la actividad anterior cuando subí a la jerarquía de navegación.

Referencia: android:launchMode

 0
Author: mumush,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-18 23:47:16

Pruebe esta solución con NavUtils.navigateUpFromSameTask (this); en la actividad secundaria: https://stackoverflow.com/a/49980835/7308789

 0
Author: Houssin Boulla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-23 12:29:37

Use finish() en la actividad para retroceder cuando esté en su evento de clic.

 -1
Author: RajaReddy PolamReddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-05 07:00:12