onBackPressed() 已弃用。还有什么选择呢?

Rum*_*tel 178 navigation android kotlin deprecation-warning android-tiramisu

我已经升级到targetSdkVersion和。compileSdkVersion33

我现在收到一条警告,告诉我onBackPressed已被弃用。

我看到建议使用android.window.OnBackInvokedCallbackandroidx.activity.OnBackPressedCallback来处理后退导航。任何人都可以帮助我使用更新的方法吗?

例子

onBackPressed已弃用

使用案例

我在onBackPressed()if (isTaskRoot) {}方法内部使用来检查该活动是否是活动堆栈上的最后一个活动。

override fun onBackPressed() {
    if (isTaskRoot) { // Check whether this activity is last on the activity stack. (Check whether this activity opened from a Push Notification.)
        startActivity(Intent(mContext, Dashboard::class.java))
        finish()
    } else {
        finishWithResultOK()
    }
}
Run Code Online (Sandbox Code Playgroud)

jai*_*yta 139

将 onBackPressed() 替换为以下代码。

onBackPressedDispatcher.onBackPressed()
Run Code Online (Sandbox Code Playgroud)

  • 对于片段 - requireActivity().onBackPressedDispatcher.onBackPressed() (8认同)

Zai*_*ain 128

根据您的 API 级别注册:

这需要至少使用appcompat:1.6.0-alpha03;目前是1.6.0-alpha04

 implementation 'androidx.appcompat:appcompat:1.6.0-alpha04'
Run Code Online (Sandbox Code Playgroud)
// 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()
        }
    })
}

// ====================================================
/* Or for lambda simplicity: */
// ====================================================
if (BuildCompat.isAtLeastT()) {
    onBackInvokedDispatcher.registerOnBackInvokedCallback(
        OnBackInvokedDispatcher.PRIORITY_DEFAULT
    ) {
        // Back is pressed... Finishing the activity
        finish()
    }
} else {
    onBackPressedDispatcher.addCallback(this /* lifecycle owner */) {
        // Back is pressed... Finishing the activity
        finish()
    }
}


Run Code Online (Sandbox Code Playgroud)

更新:

感谢@ianhanniballake 评论;OnBackPressedDispatcher即使在 API 级别 33+ 中也可以使用

当使用 Activity 1.6+ 时,OnBackPressedDispatcher 已经在内部使用 Android T 特定的 API,

所以,你可以这样做:

// kotlin
import androidx.activity.addCallback

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

// ====================================================
/* Or for lambda simplicity: */
// ====================================================
onBackPressedDispatcher.addCallback(this /* lifecycle owner */) {
    // Back is pressed... Finishing the activity
    finish()
}

Run Code Online (Sandbox Code Playgroud)
// java
import androidx.activity.OnBackPressedCallback;

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

请注意,您不应覆盖,onBackPressed()因为这会使onBackPressedDispatcher回调不触发;检查这个答案以澄清这一点。

  • 使用 Activity 1.6+ 时,“OnBackPressedDispatcher”已经在内部使用 Android T 特定 API,因此绝对没有理由直接使用 Android T API - 您可以在所有 API 级别上使用“OnBackPressedDispatcher”。 (14认同)

AI *_*kil 44

结合了热门答案。这是一个解决方案:

1. 当您需要按后退按钮时,复制以下内容:

注意:它会自动销毁您的活动。

button.setOnClickListener {
    onBackPressedDispatcher.onBackPressed()
}
Run Code Online (Sandbox Code Playgroud)

2.当您需要处理按下的后退按钮时,复制以下内容:

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


小智 41

只需更换

override fun onBackPressed() {
    super.onBackPressed() // Replace this deprecated line
}
Run Code Online (Sandbox Code Playgroud)

override fun onBackPressed() {
    onBackPressedDispatcher.onBackPressed() // with this line
}
Run Code Online (Sandbox Code Playgroud)

更新

鉴于它override fun onBackPressed()已被弃用,请将其替换为以下代码:

onBackPressedDispatcher.addCallback(this, object: OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
        println("Back button pressed")
        // Code that you need to execute on back press, e.g. finish()
  }
})
Run Code Online (Sandbox Code Playgroud)

将上述代码添加到活动生命周期函数中,例如onCreate(savedInstanceState:).

  • “上面的代码我们需要编写在一些方法中,比如 onCreate() 函数。” 这正是我所缺少的,谢谢。。 (6认同)

Mor*_*ori 14

Kotlin中,这种方式有效

1-删除onBackPressed()

2-下面onCreate(savedInstanceState: Bundle?)添加这些行:

 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()
                }
            })
    }
Run Code Online (Sandbox Code Playgroud)

3-定义一个新的处理函数

fun exitOnBackPressed() {
}
Run Code Online (Sandbox Code Playgroud)


小智 8

import android.os.Bundle
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder

class SampleActivity : AppCompatActivity(R.layout.activity_sample) {

    private val onBackPressedCallback: OnBackPressedCallback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            showAppClosingDialog()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
    }

    private fun showAppClosingDialog() {
        MaterialAlertDialogBuilder(this)
            .setTitle("Warning")
            .setMessage("Do you really want to close the app?")
            .setPositiveButton("Yes") { _, _ -> finish() }
            .setNegativeButton("No", null)
            .show()
    }
}
Run Code Online (Sandbox Code Playgroud)


Yas*_*ith 7

您可以使用onBackPressedDispatcher

onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
         
    }
})
Run Code Online (Sandbox Code Playgroud)

这里的“this”指的是lifeCycleOwner


Hen*_*ira 7

对于 Kotlin 用户:

如果您尝试使用“新”方式调用默认本机后退按钮功能,您可以在活动中使用以下代码。

this@MyActivity.onBackPressedDispatcher.onBackPressed()
Run Code Online (Sandbox Code Playgroud)

例子:

myCloseButton.setOnClickListener { this@MyActivity.onBackPressedDispatcher.onBackPressed() }
Run Code Online (Sandbox Code Playgroud)

上面的示例在按钮内设置了单击功能,使按钮的行为类似于本机 Android 后退按钮。

但是,如果您想自定义 onBackPressedDispatcher,您可以按照下面的示例进行操作,始终在您的 Activity 内,因为此行为需要 Activity 上下文才能工作。

自定义OnBackPressed示例:

override fun onCreate(savedInstanceState: Bundle?) {
    
   val callback: OnBackPressedCallback = object : OnBackPressedCallBack(true) {
        override fun handleOnBackPressed() {
            //ToDo Implement your custom event here    
        }
    }

    this@MyActivity.onBackPressedDispatcher.addCallback(this@MyActivity, callback)
}
Run Code Online (Sandbox Code Playgroud)

预期的结果是使任何 onBackPressedDispatcher 事件执行您想要的任何操作,或者根本不执行任何操作。但不建议这样做,因为您的用户可能会卡在屏幕中,而无法使用手机的后退按钮。因此,避免将handleOnBackPressed 覆盖保留为空。所以尝试这样的事情:

override fun handleOnBackPressed() {
    this@MyActivity.finish()
}
Run Code Online (Sandbox Code Playgroud)


Swa*_*nil 5

使用 onBackPressedDispatcher.onBackPressed() 而不是 super.onBackPressed()

override fun onBackPressed() {
  onBackPressedDispatcher.onBackPressed() 
}
Run Code Online (Sandbox Code Playgroud)