Android 10 手势导航禁用

5
TLDR: 我需要一种可以编程方式禁用Android 10手势导航的方法,以便当用户从侧面滑动时不会意外返回。
背景:Android 10引入了手势导航,取代了底部的按钮。因此,在启用它的Android 10设备上,他们可以从屏幕的任一侧滑动以返回,并从底部滑动以在主页和应用程序之间导航。然而,我正在进行AR实现,并希望锁定屏幕为竖屏,但允许用户进入横屏模式。
如果用户将其手机旋转到横屏模式,但活动被锁定为竖屏,则后退手势导航现在是从顶部滑动,这是访问全屏应用程序中状态栏的常见方法(其中这个也是),因此如果用户习惯于使用android导航,则会意外地返回并离开体验。
有谁知道如何通过编程方式禁用手势导航(但是用户如何返回/回到主页?)或者知道如何改变手势操作的方向,而不需要您的活动支持横屏?

1
你最终解决了吗?我尝试了以下代码: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { List<Rect> exclusionRects = new ArrayList(); Rect visibleRect = new Rect(); v.getWindowVisibleDisplayFrame(visibleRect); exclusionRects.add(visibleRect); getWindow().setSystemGestureExclusionRects(exclusionRects); } 但它只能在屏幕底部阻止后退手势。我希望谷歌的文档不要这么差。 - agusterodin
2个回答

3

注意:

  • 对于您的视图,setSystemGestureExclusionRects() 必须在 doOnLayout() 中调用

我的实现:

    binding.root.apply { // changing gesture rects for root view
        
        doOnLayout {
            // updating exclusion rect
            val rects = mutableListOf<Rect>()
            rects.add(Rect(0,0,width,(150 * resources.displayMetrics.density).toInt()))
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                systemGestureExclusionRects = rects
            }
        }
        
    }
  • 我从顶部向下排除了150dp的手势,宽度则全部排除(仅用于测试)

@Dev4Life的答案虽然有帮助,但我直到访问文档后才成功:

Android文档:setSystemGestureExclusionRects


1
很容易通过编程来阻止手势,但是你无法在两侧完全阻止手势。因此,你需要决定要禁用屏幕的多少部分手势?
以下是代码:
  • Define this code in your Utils class.

     static List<Rect> exclusionRects = new ArrayList<>();
    
     public static void updateGestureExclusion(AppCompatActivity activity) {
     if (Build.VERSION.SDK_INT < 29) return;
     exclusionRects.clear();
     Rect rect = new Rect(0, 0, SystemUtil.dpToPx(activity, 16), getScreenHeight(activity));
     exclusionRects.add(rect);
    
     activity.findViewById(android.R.id.content).setSystemGestureExclusionRects(exclusionRects);
     }
    
    public static int getScreenHeight(AppCompatActivity activity) {
     DisplayMetrics displayMetrics = new DisplayMetrics();
     activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
     int height = displayMetrics.heightPixels;
     return height;
    }
    
     public static int dpToPx(Context context, int i) {
     return (int) (((float) i) * context.getResources().getDisplayMetrics().density);
    }
    
  • Check if your layout is set in that activity where you want to exclude the edge getures and then apply this code.

     // 'content' is the root view of your layout xml.
     ViewTreeObserver treeObserver = content.getViewTreeObserver();
     treeObserver.addOnGlobalLayoutListener(new 
     ViewTreeObserver.OnGlobalLayoutListener() {
       @Override
       public void onGlobalLayout() {
           content.getViewTreeObserver().removeOnGlobalLayoutListener(this);
           SystemUtil.updateGestureExclusion(MainHomeActivity.this);
       }
     });
    
  • We are adding the exclusion rectangle width to 16dp to fetch the back gesture which you can change according to your preferrences.

以下是需要注意的几点:

  • 不要屏蔽两侧手势,否则用户体验会变得最糟糕。
  • "getScreenHeight(activity)" 是矩形的高度,因此,如果您想在屏幕左侧和上半部分屏蔽手势,则只需将其替换为 getScreenHeight(activity)/2。
  • new Rect() 中的第一个参数为 0,因为我们希望手势出现在左侧,如果您希望它出现在右侧,则只需输入 - "getScreenWidth(activity) - SystemUtil.dpToPx(activity, 16)"。

希望这可以永久解决您的问题。 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接