¿Cómo implementar el botón de retroceso de Android ActionBar?

137

Tengo una actividad con una vista de lista. Cuando el usuario hace clic en el elemento, se abre el elemento "visor":

List1.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {

        Intent nextScreen = new Intent(context,ServicesViewActivity.class);
        String[] Service = (String[])List1.getItemAtPosition(arg2);

        //Sending data to another Activity
        nextScreen.putExtra("data", datainfo);
        startActivityForResult(nextScreen,0);
        overridePendingTransition(R.anim.right_enter, R.anim.left_exit);
    }
});

Esto funciona bien, pero en la barra de acción la flecha hacia atrás al lado del icono de la aplicación no se activa. ¿Me estoy perdiendo de algo?

Joaolvcm
fuente
64
getActionBar().setDisplayHomeAsUpEnabled(true);en onCreate y switch (item.getItemId()) {case android.R.id.home: onBackPressed();break;}en onOptionsItemSelected? ambos en ServicesViewActivity
Selvin
77
¿Por qué no como una respuesta estantería?
KarlKarlsom

Respuestas:

263

Selvin ya publicó la respuesta correcta. Aquí, la solución en código bonito:

public class ServicesViewActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // etc...
        getActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }
}

La función NavUtils.navigateUpFromSameTask(this)requiere que defina la actividad principal en el archivo AndroidManifest.xml

<activity android:name="com.example.ServicesViewActivity" >
    <meta-data
     android:name="android.support.PARENT_ACTIVITY"
     android:value="com.example.ParentActivity" />
</activity>

Ver aquí para más lectura.

Surffan
fuente
1
En mi situación, estaba buscando una manera de no llamar al Creador del padre al regresar a él. Para hacer esto, utilicé su implementación, pero llamé terminar () en lugar de NavUtils.navigateUpFromSameTask (esto). finish () llama a mi onStart en lugar de onCreate, que era más ideal para mí.
Jon
Establecer metadatos en manifiesto es una clave para que el botón de navegación funcione
VSB
Use en getActionBar().setDisplayHomeAsUpEnabled(true);caso de que esté utilizando bibliotecas de soporte.
Abhinav Upadhyay
¿Cómo se cambia la dirección de la "limpieza"? Por defecto, la implementación de esta navegación hacia atrás barre la pantalla de derecha a izquierda, y parece que está cargando una nueva pantalla. Sin embargo, quiero que se limpie de izquierda a derecha, al igual que presionar la tecla de retroceso del dispositivo.
stingray_
Obtuve el error: causado por: java.lang.NullPointerException: intento de invocar el método virtual 'void android.app.ActionBar.setDisplayHomeAsUpEnabled (boolean)' en una referencia de objeto nulo
Jones
166

Asegúrese de que el Botón de inicio de ActionBar esté habilitado en la Actividad:

Android, API 5+:

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

ActionBarSherlock y App-Compat, API 7+:

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

Android, API 11+:

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

Ejemplo MainActivityque se extiende ActionBarActivity:

public class MainActivity extends ActionBarActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Back button
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home: 
            // API 5+ solution
            onBackPressed();
            return true;

        default:
            return super.onOptionsItemSelected(item);
        }
    }
}

De esta manera, todas las actividades que desee pueden tener la contrapresión.

Android, API 16+:

http://developer.android.com/training/implementing-navigation/ancestral.html

AndroidManifest.xml:

<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.DisplayMessageActivity"
        android:label="@string/title_activity_display_message"
        android:parentActivityName="com.example.myfirstapp.MainActivity" >
        <!-- The meta-data element is needed for versions lower than 4.1 -->
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myfirstapp.MainActivity" />
    </activity>
</application>

Ejemplo MainActivityque se extiende ActionBarActivity:

public class MainActivity extends ActionBarActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Back button
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @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);
    }
}
Jared Burrows
fuente
Me está funcionando cuando cambio getSupportActionBar (). SetDisplayHomeAsUpEnabled (true); en getActionBar (). setDisplayHomeAsUpEnabled (true); y agregó estos @SuppressLint ("NewApi") en el método onCreate por dentro y por fuera Para REF: => developer.android.com/training/implementing-navigation/…
gnganpath
1
@ganpath Cuidado, el uso de getActionBar es para API 11+ .
Jared Burrows
17

Para habilitar el botón de retroceso ActionBar, obviamente necesita una ActionBar en su Actividad. Esto lo establece el tema que está utilizando. Puede configurar el tema para su Actividad en el AndroidManfiest.xml. Si está utilizando, por ejemplo, el @android:style/Theme.NoTitleBartema, no tiene una barra de acciones. En este caso, la llamada a getActionBar()volverá nulo. Así que primero asegúrate de tener una ActionBar.

El siguiente paso es configurar la android:parentActivityNameactividad que desea navegar si presiona el botón Atrás. Esto debería hacerse en el AndroidManifest.xmltambién.

Ahora puede habilitar el botón de retroceso en el onCreatemétodo de su actividad "secundaria".

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

Ahora debe implementar la lógica para el botón Atrás. Simplemente anule el onOptionsItemSelectedmétodo en su actividad "secundaria" y verifique la identificación del botón Atrás que está android.R.id.home.

Ahora puede activar el método NavUtils.navigateUpFromSameTask(this); PERO si no ha especificado el android:parentActivityNameen usted, AndroidManifest.xmlesto bloqueará su aplicación.

A veces esto es lo que quieres porque te recuerda que olvidaste "algo". Entonces, si desea evitar esto, puede verificar si su actividad tiene un padre utilizando el getParentActivityIntent()método. Si esto devuelve nulo, no ha especificado el padre.

En este caso, puede activar el onBackPressed()método que básicamente hace lo mismo que si el usuario presionara el botón Atrás en el dispositivo. Una buena implementación que nunca bloquea tu aplicación sería:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            if (getParentActivityIntent() == null) {
                Log.i(TAG, "You have forgotten to specify the parentActivityName in the AndroidManifest!");
                onBackPressed();
            } else {
                NavUtils.navigateUpFromSameTask(this);
            }
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Tenga en cuenta que la animación que ve el usuario es diferente entre NavUtils.navigateUpFromSameTask(this);y onBackPressed().

Depende de usted qué camino tomar, pero la solución me pareció útil, especialmente si utiliza una clase base para todas sus actividades.

dknaack
fuente
10

Archivo de AndroidManifest:

    <activity android:name=".activity.DetailsActivity">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="br.com.halyson.materialdesign.activity.HomeActivity" />
    </activity>

agregar en DetallesActividad:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);   
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

es trabajo :]

Sågär Śåxëńá
fuente
Parece que esta es la forma más fácil para mí. Gracias
TuanDPH
3

https://stackoverflow.com/a/46903870/4489222

Para lograr esto, simplemente hay dos pasos,

Paso 1: vaya a AndroidManifest.xml y agregue el parámetro en la etiqueta - android: parentActivityName = ". Home.HomeActivity"

ejemplo:

 <activity
    android:name=".home.ActivityDetail"
    android:parentActivityName=".home.HomeActivity"
    android:screenOrientation="portrait" />

Paso 2: en ActivityDetail agregue su acción para la página / actividad anterior

ejemplo:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
      case android.R.id.home: 
          onBackPressed();
          return true;
   }
   return super.onOptionsItemSelected(item);}
}
Vivek Hande
fuente
3

En el método OnCreate agregue esto:

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

Luego agregue este método:

@Override
public boolean onSupportNavigateUp() {
    onBackPressed();
    return true;
}
Marco Concas
fuente
1
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

en onCreatedmétodo para los nuevos apis.

Kartik Garasia
fuente
1

Si está utilizando la barra Google, estaba enfrentando el mismo problema. Resolví siguiendo estos dos pasos

  1. En el AndroidManifest.xml
<activity android:name=".activity.SecondActivity" android:parentActivityName=".activity.MainActivity"/>
  1. En la segunda actividad, agregue estos ...
Toolbar toolbar = findViewById(R.id.second_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
usuario2823506
fuente
0

Los siguientes pasos son suficientes para retroceder:

Paso 1: este código debe estar en Manifest.xml

<activity android:name=".activity.ChildActivity"
        android:parentActivityName=".activity.ParentActivity"
        android:screenOrientation="portrait">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".activity.ParentActivity" /></activity>

Paso 2: no darás

finish();

en su actividad para padres al comenzar la actividad para niños.

Paso 3: si necesita volver a la Actividad principal desde la Actividad secundaria, solo debe dar este código para la Actividad secundaria.

startActivity(new Intent(ParentActivity.this, ChildActivity.class));
Kumar VL
fuente
0

Sobre la base de la respuesta de Jared, tuve que habilitar e implementar el comportamiento del botón de retroceso de la barra de acción en varias actividades y creé esta clase auxiliar para reducir la duplicación de código.

public final class ActionBarHelper {
    public static void enableBackButton(AppCompatActivity context) {
        if(context == null) return;

        ActionBar actionBar = context.getSupportActionBar();
        if (actionBar == null) return;

        actionBar.setDisplayHomeAsUpEnabled(true);
    }
}

Uso en una actividad:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...

    ActionBarHelper.enableBackButton(this);
}
datchung
fuente