- 在 BaseActivity.kt 中代码实现:
kotlin
abstract class BaseActivity<VB: ViewBinding>: AppCompatActivity() {
...
override fun onCreate(savedInstanceState: Bundle?) {
...
// 触发滑动逻辑
triggerSwipeBack()
}
/**
* 滑动逻辑
*/
open fun onSwipeBack() {}
@SuppressLint("ClickableViewAccessibility")
private fun triggerSwipeBack() {
val rootView = viewBinding.root
rootView.isClickable = true
rootView.isFocusable = true
rootView.setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
touchStartX = event.rawX
}
MotionEvent.ACTION_UP -> {
val touchEndX = event.rawX
val slideDistance = touchEndX - touchStartX
LogUtils.d(className, "slideDistance: $slideDistance")
// 判断:左右滑动距离足够
if (slideDistance.absoluteValue > 100) {
// 触发边缘滑动逻辑
LogUtils.d(className, "触发滑动逻辑")
onSwipeBack()
}
}
}
// 返回false,不拦截原有点击、滚动等事件
false
}
}
}
- MainActivity.kt 中
kotlin
class MainActivity: BaseActivity<ActivityMainBinding>() {
...
// 导航控制器
private var navController: NavController? = null
// 双击退出计时变量
private var lastBackTime = 0L
override fun onCreate(savedInstanceState: Bundle?) {
...
// 关联导航
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment)
if (navHostFragment != null) {
navController = (navHostFragment as NavHostFragment).navController
navController?.let { controller ->
// 关联底部导航
viewBinding.bottomNavigation.setupWithNavController(controller)
}
}
}
/**
* 触发滑动逻辑
*/
override fun onSwipeBack() {
navController?.let {
// 判断当前页面是否有上层回退页面,若无则当前是Tab首页
if (it.previousBackStackEntry == null) {
val now = System.currentTimeMillis()
if (now - lastBackTime < 2000) {
// 两次间隔小于2秒,直接退出App
finish()
} else {
// 第一次侧滑/返回,提示,更新上次点击时间
Toast.makeText(this, R.string.swipe_exit_app_tip, Toast.LENGTH_SHORT).show()
lastBackTime = now
}
} else {
// 有上层回退页面,则直接返回
it.popBackStack()
}
}
}
}