【Android 控件】使用 Navigation 实现底部导航功能时左右滑动退出页面功能

  • 在 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()
            }
        }
    }
    
}
相关推荐
tianshi48519 小时前
Android 应用启动窗口(Splash Screen)的创建与销毁流程
android
脚踏实地,坚持不懈!9 小时前
ICU Calendar 实际工作问题排查手册
android
ii_best9 小时前
安卓脚本/ios开发软件按键精灵实战:自动定位弹窗广告关闭按钮坐标的通用方案
android·ios·自动化
天空之城--10 小时前
Android Jetpack Compose 状态管理浅析
android·android jetpack
企业数字化笔记14 小时前
固定资产财务账与实物账怎么对账?折旧快照、差异检测与SQL核对
android·数据库·sql
千里马-horse15 小时前
第 66 章:在 Android 上运行 Windows 游戏
android·aosp
云边有个稻草人19 小时前
飞牛 NAS 远程访问实战:星空组网连接 Mac 与安卓,从 Compose 部署到 5G 验证
android·5g·macos
聚美智数20 小时前
手机号归属地-手机号归属地查询-手机归属地-运营商归属地
android·智能手机
恋猫de小郭20 小时前
Shopify 从 React Native 回到 Swift/Kotlin,但是你以为有手就行??
android·前端·ios
菠萝加点糖20 小时前
Android ChipGroup 使用说明
android