Android: botón Atrás en la barra de título

111

En muchas aplicaciones (Calendario, Drive, Play Store) cuando tocas un botón e ingresas una nueva actividad, el ícono en la barra de título se convierte en un botón de retroceso, pero para la aplicación que estoy creando, no hace eso. ¿Cómo hago para que ese ícono lo lleve de regreso a la pantalla anterior?

Dibujó
fuente
Pruebe getSupportActionBar () en el ejemplo de OnCreate aquí freakyjolly.com/how-to-add-back-arrow-in-android-activity
Code Spy

Respuestas:

145

Hay dos pasos sencillos para crear un botón de retroceso en la barra de título:

Primero, haga clic en el ícono de la aplicación usando el siguiente código en la actividad en cuya barra de título desea tener un botón de retroceso:

ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);

Después de haber agregado el código anterior, verá aparecer una flecha hacia atrás a la izquierda del icono de la aplicación.

ingrese la descripción de la imagen aquí

En segundo lugar, después de haber hecho lo anterior, aún debe crear un código que aproveche el evento de clic. Para hacerlo, tenga en cuenta que, cuando hace clic en el icono de la aplicación, onOptionsItemSelectedse llama a un método. Entonces, para volver a la actividad anterior, agregue ese método a su actividad y coloque un Intentcódigo en él que lo regresará a la actividad anterior. Por ejemplo, digamos que se llama la actividad a la que está intentando volverMyActivity . Para volver a él, escriba el método de la siguiente manera:

public boolean onOptionsItemSelected(MenuItem item){
    Intent myIntent = new Intent(getApplicationContext(), MyActivity.class);
    startActivityForResult(myIntent, 0);
    return true;
}

¡Eso es!

(En la API de desarrolladores de Android, recomienda jugar con el manifiesto y agregar cosas como android:parentActivityName. Pero eso no parece funcionar para mí. Lo anterior es más simple y más confiable).

<meta-data
      android:name="android.support.PARENT_ACTIVITY"
      android:value=".MainActivity" />

Y en tu actividad

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Luke F.
fuente
23
Lo explicó bien, pero si no está mal en su onOptionItemSelected, simplemente debe llamar a finish (); en su caso, startActivityForResult lanzará la segunda actividad y cuando presione hacia atrás desde la segunda actividad, será devuelto a la primera actividad (donde presionó el ícono de la barra de acción)
Yahya Arshad
8
Además, debe hacer eso solo si item.getItemId () es android.R.id.home
bitek
2
Como dice AS: "La invocación del método 'actionBar.setDisplayHomeAsUpEnabled (true)' puede producir java.lang.NullPointerException"
statosdotcom
1
¡Advertencia! Con una barra de herramientas, actionBar devuelve nulo con bloqueo. Vea las respuestas a continuación.
CoolMind
5
getActionBar () no funcionó para mí, la aplicación simplemente falla. getSupportActionBar () funcionó.
john ktejik
60

usa este código

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

después de eso, escribe este código en el onOptionsItemSelectedmétodo

  int id = item.getItemId();

     if (id==android.R.id.home) {
        finish();
    }
anupam sharma
fuente
1
getActionBar()me da un nulo; ¿Sabes por qué?
msysmilu
3
porque no hay ActionBar, por ejemplo, con estilo <item name = "android: windowActionBar"> false </item> <item name = "android: windowNoTitle"> true </item>
Paul Verest
47

Finalmente logré agregar correctamente el botón Atrás a la barra de acciones / barra de herramientas

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            finish();
            return true;
    }

    return super.onOptionsItemSelected(item);
}

public boolean onCreateOptionsMenu(Menu menu) {
    return true;
}
Lucy Fair
fuente
3
Esta es la única respuesta que me funciona. Gracias @LucyFair
Arda Çebi
2
Mismo. Gracias por su respuesta.
Maria
Mismo. Ninguna de las otras respuestas funciona. Esta debería haber sido la respuesta aceptada.
El Sushiboi
18

1.- Agrega la actividad a AndroidManifest.xml y asegúrate de proporcionar los metadatos:

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

2.- Agrega el siguiente código al método onCreate de la actividad:

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

3.- Anula onOptionsItemSelected y usa el método estático NavUtils.navigateUpFromSameTask () para navegar y lanzar la pila.

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

Sin embargo, el uso de navigateUpFromSameTask () es adecuado solo cuando su aplicación es el propietario de la tarea actual (es decir, el usuario comenzó esta tarea desde su aplicación). Si eso no es cierto y su actividad se inició en una tarea que pertenece a una aplicación diferente, entonces navegar hacia arriba debería crear una nueva tarea que pertenezca a su aplicación, lo que requiere que cree una nueva pila de actividades.

ciclista espacial
fuente
¡Gracias por presentar NavUtils!
AntonSack
10

Si su actividad extiende la actividad

public class YourActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_xxx);

        getActionBar().setHomeButtonEnabled(true);

        [...]
    }

    [...]
}

Si su acción extiende AppCompatActivity

public class YourActivity extends AppCompatActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_xxx);

            getSupportActionBar().setHomeButtonEnabled(true);

            [...]
        }

        [...]
    }

No hay nada más que hacer, consulte Agregar acción

[OPCIONAL] Para definir explícitamente la actividad principal, modifique su Manifest.xml de esta manera:

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

Ver Especificar la actividad de los padres

nene
fuente
1
Esto es exactamente lo que estaba buscando. Salvaste mi día. Muchas gracias.
Tashi Dendup
6

Si su actividad se extiende AppCompatActivity, debe anular el onSupportNavigateUp()método de esta manera:

public class SecondActivity extends AppCompatActivity {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_second);
       Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
       setSupportActionBar(toolbar);
       getSupportActionBar().setHomeButtonEnabled(true);
       getSupportActionBar().setDisplayHomeAsUpEnabled(true);
       ...
   }

   @Override
   public void onBackPressed() {
       super.onBackPressed();
       this.finish();
   }

   @Override
   public boolean onSupportNavigateUp() {
       onBackPressed();
       return true;
   }
}

Maneje su lógica en su onBackPressed()método y simplemente llame a ese método onSupportNavigateUp()para que el botón Atrás en el teléfono y la flecha en la barra de herramientas hagan lo mismo.

Ruzin
fuente
6

En primer lugar, en la función onCreate agregue la siguiente línea

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

y luego agregue la siguiente función en el código:

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                return true;
        }

        return super.onOptionsItemSelected(item);
    }
M Anees
fuente
6

Primero necesitas escribir estos códigos

@Override
    protected void onCreate(Bundle savedInstanceState) {
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

Luego agrega esta línea en el manifiesto

 <activity android:name=".MainActivity"
            android:parentActivityName=".PreviousActivity"></activity>

Creo que funcionará

Shahriar Ahmad
fuente
5

Si está utilizando la nueva biblioteca de soporte para 5.1 en Android Studio, puede usarla en su AppCompatActivity

 ActionBar actionBar = getSupportActionBar();
 actionBar.setHomeButtonEnabled(true);
 actionBar.setDisplayHomeAsUpEnabled(true);
 actionBar.setHomeAsUpIndicator(R.mipmap.ic_arrow_back_white_24dp);
 actionBar.setDisplayShowHomeEnabled(true);

salud.

ralphgabb
fuente
5

La forma más sencilla y la mejor práctica como explica Google aquí :

1.Agregue un padre para la actividad de su hijo en AndroidManifest.xml:

<activity 
        android:name=".ChildActivity"
        android:parentActivityName=".ParentActivity" >
</activity>

2.Active el botón de retroceso en su actividad infantil:

myActionOrActionSupportBar.setDisplayHomeAsUpEnabled(true);

Funcionó para mí, espero que también funcione para ti.

luke8800gts
fuente
esto solo es válido si la actividad solo puede tener una actividad principal. Ese es mi caso. +1
MQoder
El paso 2 no fue necesario en mi caso.
Thomio
5

Después de un tiempo de calidad que he encontrado, la opción de tema es el principal problema en mi código Y la siguiente es la forma correcta de mostrar la barra de herramientas para mí

En el archivo AndroidManifest, primero debe cambiar el estilo de su tema

Theme.AppCompat.Light.DarkActionBar
to 
Theme.AppCompat.Light.NoActionBar

luego, en su xml de actividad, debe llamar a su propia barra de herramientas como

<androidx.appcompat.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:id="@+id/toolbar"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:elevation="4dp"/>

Y luego esta barra de herramientas debería ser llamada en su archivo Java por

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

Y para la barra de herramientas que muestra U, debe verificar el nulo para evitar NullPointerException

if(getSupportActionBar() != null){
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

Para la actividad en el hogar, agregue esto

@Override
public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId()==android.R.id.home) {
            finish();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

O para su actividad deseada de regreso

public boolean onOptionsItemSelected(MenuItem item){
    Intent myIntent = new Intent(getApplicationContext(), YourActivity.class);
    startActivityForResult(myIntent, 0);
    return true;
}
MST
fuente
3

Vi tantos complejos responder, así que este es mi código. Trabajando aquí. Puede lograrlo de dos formas.

1) Compatibilidad con Android Stardard

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.NavUtils;

import android.view.MenuItem;
import android.view.View;

public class EditDiscoveryActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_discovery);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        /*toolbar.setNavigationIcon(R.drawable.ic_arrow_white_24dp);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });*/
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
    }

    @Override
    public boolean onSupportNavigateUp() {
        onBackPressed();
        return true;
    }

}

2) Utilice un icono personalizado

Si desea usar código en los comentarios, solo tiene que agregar este archivo en el dibujable, llamado ic_arrow_white_24dp.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <path
        android:fillColor="#ffffff"
        android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
    </vector>

Con este código.

toolbar.setNavigationIcon(R.drawable.ic_arrow_white_24dp);
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    finish();
                }
            });

¡Espero que ayude a algunas personas aquí!

Zhar
fuente
2

La versión ligera sin usar ActionBarActivityque todavía tiene los mismos comportamientos aquí:

public class ToolbarConfigurer implements View.OnClickListener {
    private Activity activity;

    public ToolbarConfigurer(Activity activity, Toolbar toolbar, boolean displayHomeAsUpEnabled) {
        toolbar.setTitle((this.activity = activity).getTitle());
        if (!displayHomeAsUpEnabled) return;
        toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
        toolbar.setNavigationOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        NavUtils.navigateUpFromSameTask(activity);
    }
}

Uso: Ponga new ToolbarConfigurer(this, (Toolbar) findViewById(R.id.my_awesome_toolbar), true);en onCreate.

Dios mío
fuente
Esto encaja con el nuevo widget de la barra de herramientas que se incluye en la biblioteca de soporte. ¡¡Gracias!!
Clocker
2

Debe agregar el código mencionado a continuación en el archivo de manifiesto. Busque la actividad en la que desea agregar la función de flecha hacia atrás. Si encuentra el indicado, entonces está bien o cree la actividad.

<activity android:name=".SearchActivity">

</activity>

Luego agregue las siguientes tres líneas de código en el medio.

<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.raqib.instadate.MainActivity" />

Y no olvide agregar este fragmento de código en onCreate (); método de su actividad particular en el que necesita la flecha hacia atrás.

        Toolbar toolbar = (Toolbar) findViewById(R.id.searchToolbar);
    setSupportActionBar(toolbar);
    try{
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }catch(NullPointerException e){
       Log.e("SearchActivity Toolbar", "You have got a NULL POINTER EXCEPTION");
    }

Así es como resolví el problema. Gracias.

Muhammad Raqib
fuente
2

Las otras respuestas no mencionan que también puede configurar esto en el XML de su Toolbarwidget:

app:navigationIcon="?attr/homeAsUpIndicator"

Por ejemplo:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    app:navigationIcon="?attr/homeAsUpIndicator"
    app:popupTheme="@style/AppTheme.PopupOverlay"
    app:title="@string/title_activity_acoustic_progress" />
Michael Litvin
fuente
2

Todo lo que necesitas hacer en 2020:
(considerando que quieres volver a MainActivity)

protected void onCreate(Bundle savedInstanceState){
    ...
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

public boolean onOptionsItemSelected(MenuItem item) {
    Intent myIntent = new Intent(getApplicationContext(), MainActivity.class);
    startActivityForResult(myIntent, 0);
    return true;
}
Ahmed Abdullah
fuente
Eso es interesante, pero está asumiendo que queremos volver a MainActivity. ¿Cómo redirigiría a alguna actividad anterior?
mayid
1

También se puede hacer sin código especificando una actividad principal en el manifiesto de la aplicación. Si desea un botón de retroceso en la Actividad B que irá a la Actividad A, simplemente agregue la Actividad A como padre de la Actividad B en el manifiesto.

aby4reality
fuente
1

Para kotlin:

   override fun onOptionsItemSelected(item: MenuItem): Boolean {
        onBackPressed();
        return true;
    }
Raluca Lucaci
fuente
1

Necesitaba mezclar algunas respuestas para obtener la respuesta correcta para mí porque mi aplicación tiene 3 actividades que pueden ir y venir en cualquier momento. Actividad1> Actividad2> Actividad3. Cuando estaba haciendo algo en mi actividad3, el botón de retroceso estaba retrocediendo correctamente a Actividad2. Sin embargo, desde Activity2, usando finish(), estaba retrocediendo a Activity3 y no a Activity1. Y estoy ampliando AppCompatActivity. Entonces, mi solución fue:

public class Activity2 extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            ...

            getSupportActionBar().setHomeButtonEnabled(true);
        }
    }

en AndroidManifest.xml:

<activity android:name=".activities.Activity2"
           android:parentActivityName="com.example.appname.activities.Activity1">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.example.appname.activities.Activity1" />
        </activity>

y finalmente, el botón de acción en mi menú (barra de acciones):

public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            ...

            case android.R.id.home:
                NavUtils.navigateUpFromSameTask(this);
                return true;

        }

        return super.onOptionsItemSelected(item);

    }

Usar NavUtils.navigateUpFromSameTask(this);funcionó para mí, en lugar de finish().

Gi Tavares
fuente
1

Simplemente comparto algo que me ayudó y puede ser útil para otros. Aunque la mayoría de las respuestas aquí son correctas, al usar el getActionBar().setDisplayHomeAsUpEnabled(true);, esto no funcionó para mí. El problema que tuve fue que estaba tratando de crear una segunda actividad manualmente, pero hay más detalles involucrados.
Lo que realmente resolvió mi problema fue seguir el tutorial de desarrolladores de Android ( https://developer.android.com/training/basics/firstapp/starting-activity ) para crear una segunda actividad con las herramientas propias de Android Studio:

Create the second activity
1. In the Project window, right-click the app folder and select New > Activity > Empty Activity.
2. In the Configure Activity window, enter "DisplayMessageActivity" for Activity Name and click Finish (leave all other properties set to the defaults).
Android Studio automatically does three things:
- Creates the DisplayMessageActivity file.
- Creates the corresponding activity_display_message.xml layout file.
- Adds the required <activity> element in AndroidManifest.xml.
ofri cofri
fuente
0

También puede simplemente poner onBackPressed()su oyente onClick. Esto hace que su botón actúe como los botones de "copia de seguridad" predeterminados en las aplicaciones de Android.

usuario3700215
fuente
0
Toolbar toolbar=findViewById(R.id.toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

if (getSupportActionBar()==null){
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setDisplayShowHomeEnabled(true);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==android.R.id.home)
    finish();
return super.onOptionsItemSelected(item);
}
Abhay Agrawal
fuente
0

Esto funciona para mí. Supongamos que hay dos actividades (Activityone, Activitytwo)

Dentro de Activitytwo use este código

@Override
protected void onCreate(Bundle savedInstanceState) {
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

En Activityone

//when you need to go second activity
startActivity(new Intent(Activityone.this, Activitytwo.class));

Esto debe incluirse en la segunda actividad dentro del archivo de manifiesto

<activity android:name=".Activitytwo"
        android:parentActivityName=".Activityone"></activity>

Y el resultado sería así

ingrese la descripción de la imagen aquí

Muhaiminur Rahman
fuente
0
  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.YourxmlFileName);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

  public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id==android.R.id.home) {
            finish();
            return true;
        }
        return false;
    }
S. Adikaram
fuente