onBackPressed() en desuso, ¿cuál es la alternativa?

5 minutos de lectura

Avatar de usuario de Rumit Patel
Rumit Patel

he actualizado targetSdkVersion y compileSdkVersion a 33.

Ahora recibiendo advertencia onBackPressed es obsoleto.

Se sugiere utilizar el uso OnBackInvokedCallback o androidx.activity.OnBackPressedCallback para manejar la navegación hacia atrás en su lugar. Cualquiera puede ayudarme a usar el método actualizado.

Ejemplo:

onBackPressedObsoleto

Caso de uso: yo suelo if (isTaskRoot) {} en el interior onBackPressed(){} El método para verificar la actividad es el último en la pila de actividades.

override fun onBackPressed() {
    if (isTaskRoot) { // Check this activity is last on the activity-stack.(Check Whether This activity opened from Push-Notification)
        startActivity(Intent(mContext, Dashboard::class.java))
        finish()
    } else {
        finishWithResultOK()
    }
}

  • Si solo estás llamando super.onBackPressed(), entonces puede eliminar el método por completo, ya que no está escribiendo ningún comportamiento de retroceso personalizado. Si usted son escribiendo un comportamiento de respaldo personalizado, muestre su código.

    – ianhanniballake

    15 de junio a las 16:19

  • @ianhanniballake, estoy usando if (isTaskRoot) {} en el interior onBackPressed() para verificar que la actividad es la última en la pila de actividades. También he actualizado la pregunta.

    – Rumit Patel

    23 de junio a las 13:08

  • No debería estar haciendo eso en absoluto en ningún nivel de API. Por favor incluya su código.

    – ianhanniballake

    23 de junio a las 13:27

  • La página de detalles del producto se abre al hacer clic en la notificación push. Si la aplicación está cerrada, ahora el usuario ingresa en la página de detalles del producto haciendo clic en la notificación automática. Luego, al hacer clic en Backpress, el usuario no debe salir directamente de la aplicación. para este caso yo uso onBackPressed().

    – Rumit Patel

    23 de junio a las 14:36

  • ¿Descubriste el isTaskRoot ¿condicional? La mayoría de las respuestas parecen estar muy enfocadas en casos de uso triviales.

    – TWiStErRob

    9 oct a las 21:03

Avatar de usuario de Zain
Zaín

Según su registro de nivel de API:

Esto requiere al menos usar appcompat:1.6.0-alpha03; la corriente es 1.6.0-alpha04:

 implementation 'androidx.appcompat:appcompat:1.6.0-alpha04'
// kotlin
import androidx.activity.addCallback

if (BuildCompat.isAtLeastT()) {
    onBackInvokedDispatcher.registerOnBackInvokedCallback(
        OnBackInvokedDispatcher.PRIORITY_DEFAULT
    ) {
        // Back is pressed... Finishing the activity
        finish()
    }
} else {
    onBackPressedDispatcher.addCallback(this /* lifecycle owner */, object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            // Back is pressed... Finishing the activity
            finish()
        }
    })
}

ACTUALIZAR:

Gracias al comentario de @ianhanniballake; solo puedes usar OnBackPressedDispatcher incluso en el nivel API 33+

El OnBackPressedDispatcher ya usará la API específica de Android T internamente cuando use la Actividad 1.6+,

Entonces, solo puedes hacer:

// kotlin
import androidx.activity.addCallback

onBackPressedDispatcher.addCallback(this /* lifecycle owner */, object : OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
        // Back is pressed... Finishing the activity
        finish()
    }
})


// java
import androidx.activity.OnBackPressedCallback;

getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
    @Override
    public void handleOnBackPressed() {
        // Back is pressed... Finishing the activity
        finish();
    }
});

Tenga en cuenta que no debe anular el onBackPressed() ya que eso hará que onBackPressedDispatcher devolución de llamada para no disparar; verifique esta respuesta para aclarar eso.

  • los OnBackPressedDispatcher ya va a usar la API específica de Android T internamente cuando use la Actividad 1.6+, por lo que no hay absolutamente ninguna razón para usar las API de Android T directamente; solo puede usar la OnBackPressedDispatcher en todos los niveles de API.

    – ianhanniballake

    15 de junio a las 16:46

  • El problema que veo aquí es que ahora tienes dos formas de manejar el back press, lo cual es un poco complicado. ¿Hay alguna forma de restringir la anulación de la antigua onBackPressed?

    – DEVS bit a bit

    25 de junio a las 22:02

  • como puedo invocar OnBackPressedCallback handleOnBackPressed programáticamente, digamos que tengo un botón que necesita llamar onBackPressed() programáticamente?

    – DEVS bit a bit

    25 de junio a las 22:14


  • @BitwiseDEVS AFAIK, todavía onBackPressed() expuesto a los desarrolladores; en algunas API más nuevas, esto no debería ser cierto; pero manejar ambos simultáneamente no es tan correcto como la nota que queda al final de la respuesta.

    – Zaín

    27 de junio a las 22:20


  • @Zain Fue mi culpa: estaba extendiendo Activity en lugar de AppCompatActivity. ¡Lo siento!

    – Luis A. Florit

    16 oct a las 0:48

Reemplace onBackPressed() con el siguiente código.

onBackPressedDispatcher.onBackPressed()

  • ¡Simple y limpio!

    – Rajesh Koshti

    8 de noviembre a las 10:03

Avatar de usuario de Yasiru Nayanajith
Yasiru Nayanajith

Podrías usar el onBackPressedDispatcher

onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
         
    }
})

aquí “esto” significa el propietario del ciclo de vida

Avatar de usuario de AIShakil
AIShakil

Con una combinación de las mejores respuestas. Aquí hay una solución:

1. Cuando necesite presionar el botón Atrás, copie esto:

Nota: destruirá automáticamente su actividad.

button.setOnClickListener {
    onBackPressedDispatcher.onBackPressed()
}

2. Cuando necesite manejar el botón Atrás presionado, copie esto:

onBackPressedDispatcher.addCallback(this, object: OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
        // Whatever you want
        // when back pressed
        println("Back button pressed")
        finish()
    }
})

En kotlinesta manera está funcionando

1- Quitar onBackPressed()

2- abajo onCreate(savedInstanceState: Bundle?) añade estas líneas:

 if (Build.VERSION.SDK_INT >= 33) {
        onBackInvokedDispatcher.registerOnBackInvokedCallback(
            OnBackInvokedDispatcher.PRIORITY_DEFAULT
        ) {
           
            exitOnBackPressed()
        }
    } else {
        onBackPressedDispatcher.addCallback(
            this,
            object : OnBackPressedCallback(true) {
                override fun handleOnBackPressed() {
                  
                    Log.i("TAG", "handleOnBackPressed: Exit")
                    exitOnBackPressed()
                }
            })
    }

3- Definir una nueva función para el manejo

fun exitOnBackPressed() {
}

Puede usar OnBackInvokedCallback

OnBackInvokedCallback como se describe en la documentación y siga este guía aquí para actualizar tu código

Avatar de usuario de Ananthakrishnan KR
Ananthakrishnan KR

Bonificación: para cerrar DrawerLayout cuando está onBackPressed, use como se muestra a continuación (según esta charla de E/S),

val callback = onBackPressedDispatcher.addCallback(this, false) {
    binding.drawerLayout.closeDrawer(GravityCompat.START)
}
            
binding.drawerLayout.addDrawerListener(object : DrawerListener {  
        
    override fun onDrawerOpened(drawerView: View) {
        callback.isEnabled = true
    }
        
    override fun onDrawerClosed(drawerView: View) {
        callback.isEnabled = false
    }

    override fun onDrawerSlide(drawerView: View, slideOffset: Float) = Unit    
    override fun onDrawerStateChanged(newState: Int) = Unit
})

¿Ha sido útil esta solución?