Android Framework手势导航左右滑有效区域的判定

发布于:2025-06-26 ⋅ 阅读:(19) ⋅ 点赞:(0)

简介

用于手势导航左、右滑动触摸区域的判断是在EdgeBackGestureHandler.java代码中。不同的版本的Android存放的位置是不一样的。
在这里插入图片描述
当在有效的区域滑动时,会退出当前的Activity页面。

代码位置

安卓11
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java

如果是mtk
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java

安卓12
frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java

代码分析

这里以安卓11 EdgeBackGestureHandler.java代码为例

    private boolean isWithinTouchRegion(int x, int y) {
        // Disallow if we are in the bottom gesture area
        if (y >= (mDisplaySize.y - mBottomGestureHeight)) {
            return false;
        }

        // If the point is way too far (twice the margin), it is
        // not interesting to us for logging purposes, nor we
        // should process it.  Simply return false and keep
        // mLogGesture = false.
        if (x > 2 * (mEdgeWidthLeft + mLeftInset)
                && x < (mDisplaySize.x - 2 * (mEdgeWidthRight + mRightInset))) {
            return false;
        }

        // Denotes whether we should proceed with the gesture.
        // Even if it is false, we may want to log it assuming
        // it is not invalid due to exclusion.
        boolean withinRange = x <= mEdgeWidthLeft + mLeftInset
                || x >= (mDisplaySize.x - mEdgeWidthRight - mRightInset);

        // Always allow if the user is in a transient sticky immersive state
        if (mIsNavBarShownTransiently) {
            mLogGesture = true;
            return withinRange;
        }

        if (mExcludeRegion.contains(x, y)) {
            if (withinRange) {
                // Log as exclusion only if it is in acceptable range in the first place.
                mOverviewProxyService.notifyBackAction(
                        false /* completed */, -1, -1, false /* isButton */, !mIsOnLeftEdge);
                // We don't have the end point for logging purposes.
                mEndPoint.x = -1;
                mEndPoint.y = -1;
                mLogGesture = true;
                logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_EXCLUDED);
            }
            return false;
        }

        mInRejectedExclusion = mUnrestrictedExcludeRegion.contains(x, y);
        mLogGesture = true;
        return withinRange;
    }

这段代码是 Android 系统中处理边缘返回手势时的触摸区域检测逻辑,其核心作用是判断用户触摸是否发生在有效的边缘返回触发区域内。以下是对该方法的详细解释:

方法概述

isWithinTouchRegion(int x, int y) 方法接收触摸点的坐标,返回一个布尔值表示该触摸是否应被视为边缘返回手势的起点。在此过程中,它会进行多种条件检查并记录相关统计信息。

主要逻辑分析

  1. 底部手势区域过滤
if (y >= (mDisplaySize.y - mBottomGestureHeight)) {
    return false;
}
  • 功能:如果触摸点位于屏幕底部的手势区域(如底部导航栏区域),则不视为边缘返回手势。
  • 目的:避免底部导航操作与边缘返回手势冲突。
  1. 远离边缘区域的快速过滤
if (x > 2 * (mEdgeWidthLeft + mLeftInset)
        && x < (mDisplaySize.x - 2 * (mEdgeWidthRight + mRightInset))) {
    return false;
}
  • 功能:如果触摸点距离左右边缘都超过边缘宽度的两倍,则快速判定为无效区域。
  • 优化目的:减少后续复杂判断的执行,提高性能。
  1. 边缘区域判定
boolean withinRange = x <= mEdgeWidthLeft + mLeftInset
        || x >= (mDisplaySize.x - mEdgeWidthRight - mRightInset);
  • 功能:判断触摸点是否位于左侧或右侧的边缘返回触发区域内。
  • 参数说明:
    mEdgeWidthLeft/Right:左右边缘触发区域的宽度。
    mLeftInset/RightInset:边缘内边距(可能因设备或显示情况而异)。
  1. 临时导航栏状态处理
if (mIsNavBarShownTransiently) {
    mLogGesture = true;
    return withinRange;
}
  • 功能:当导航栏处于临时显示状态时,直接根据边缘区域判定结果返回,并记录手势日志。
  1. 排除区域处理
if (mExcludeRegion.contains(x, y)) {
    if (withinRange) {
        // 记录排除区域的手势尝试
        mOverviewProxyService.notifyBackAction(...);
        mLogGesture = true;
        logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_EXCLUDED);
    }
    return false;
}
  • 功能:如果触摸点位于系统定义的排除区域(如应用自定义的非响应区域),则返回无效。
  • 特殊处理:若触摸点同时满足边缘区域条件,会记录一个排除类型的手势日志。
  1. 无限制排除区域标记与最终结果
mInRejectedExclusion = mUnrestrictedExcludeRegion.contains(x, y);
mLogGesture = true;
return withinRange;
  • 功能:
    标记触摸点是否位于无限制排除区域(可能影响后续手势处理)。
    记录手势日志并返回边缘区域判定结果。

限定左滑无效

限定左滑无效,只保留右滑功能

// 修改前:包含左右两侧边缘
boolean withinRange = x <= mEdgeWidthLeft + mLeftInset
        || x >= (mDisplaySize.x - mEdgeWidthRight - mRightInset);

// 修改后:仅保留右侧边缘
boolean withinRange = x >= (mDisplaySize.x - mEdgeWidthRight - mRightInset);

相关文章

Android 13屏蔽Activity或包的手势禁止滑动退出
安卓framework美化手势导航侧滑返回UI
Android Framework禁用手势上滑及按钮进多任务的功能
Android Framework手势导航左右滑有效区域的判定
作者:帅得不敢出门


网站公告

今日签到

点亮在社区的每一天
去签到