Android回退按钮处理方法总结

引言

1. Activity 级别的回退处理

方法一:重写 onBackPressed()

Kotlin 复制代码
@Override
public void onBackPressed() {
    if (shouldCustomHandleBack) {
        // 自定义回退逻辑
        handleCustomBackAction();
    } else {
        // 默认行为
        super.onBackPressed();
    }
}

方法二:使用 onBackPressedDispatcher(推荐)

Kotlin 复制代码
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if (shouldInterceptBackPress) {
                    // 拦截回退事件
                    showExitConfirmation()
                } else {
                    // 允许默认行为
                    isEnabled = false
                    onBackPressed()
                }
            }
        })
    }
}

用的时候发现,官方已经onBackPressed 废弃了。

现在推荐这样处理"返回":在 Activity 里 用 OnBackPressedDispatcher + OnBackPressedCallback。

正文

在 Activity 里

用 OnBackPressedDispatcher + OnBackPressedCallback。

Kotlin 复制代码
class MainActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    onBackPressedDispatcher.addCallback(this,
      object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
          // TODO: 自定义返回逻辑
          // e.g. 先关闭抽屉/弹窗,否则再退出
          finish()
        }
      }
    )
  }
}

如果你只是想"触发默认返回",调用:

onBackPressedDispatcher.onBackPressed()

在 Fragment 里

用 viewLifecycleOwner 绑定生命周期(避免内存泄露):

Kotlin 复制代码
class DemoFragment : Fragment(R.layout.fragment_demo) {
  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    requireActivity().onBackPressedDispatcher.addCallback(
      viewLifecycleOwner,
      object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
          // TODO: Fragment 内自定义返回
          // 例如先消费一次返回,不想消费时可以:
          // isEnabled = false
          // requireActivity().onBackPressedDispatcher.onBackPressed()
        }
      }
    )
  }
}

如果用了 NavController,一般无需手动拦截:

// Toolbar 左上角返回键

toolbar.setNavigationOnClickListener { navController.navigateUp() }

想自定义时,再用上面的 OnBackPressedCallback 协调。

Jetpack Compose

用 androidx.activity.compose.BackHandler:

Kotlin 复制代码
BackHandler(enabled = true) {
  // 自定义返回
}

小结

  • 不要再重写 onBackPressed()。

  • 首选 OnBackPressedDispatcher + OnBackPressedCallback(Activity/Fragment/Compose 都有对应做法)。

  • 用 Navigation 时,默认就支持返回;需要拦截再加 Callback。

  • Android 13+ 若要玩预测性返回的高级用法,再考虑 OnBackInvokedCallback。

相关推荐
超级架构师19 分钟前
PRAXO-CORE 2.5.0:用 conformance 和显式边界构建 Go Agent 框架
开发语言·人工智能·后端·golang·ai编程·智能体框架·praxo-core
叼烟扛炮1 小时前
Linux 学习笔记(四十三):网络编程进阶——自定义协议解决 TCP 粘包与守护进程
linux·开发语言·网络·笔记·tcp/ip
三少爷的鞋1 小时前
Java 线程自上而下,Kotlin 协程自下而上
android
LMT流氓兔2 小时前
第五单元——第十六课:给书店助手加上网页界面
java·开发语言·jvm·人工智能·oracle·langchain·1024程序员节
专注仿真2 小时前
梯度提升类(XFBoost)算法详解与代码实例
开发语言·人工智能·python·算法·大模型训练·控制算法
外收内放2 小时前
Python基础语法练习题(75)
开发语言·python·学习
好的佩奇3 小时前
Dart 之增强枚举
android·flutter·dart
starzy19903 小时前
Scala循环与判断:一切皆表达式的控制流
开发语言·人工智能·scala
starzy19903 小时前
Scala类和对象:从构造器到样例类的完整指南
开发语言·后端·scala
梦影_3 小时前
MySQL进阶教程(五)—— SQL调优(下)
android·大数据·数据库·后端·sql·mysql·database