Android 10 手势导航禁用

Posted

技术标签:

【中文标题】Android 10 手势导航禁用【英文标题】:Android 10 gesture navigation disable 【发布时间】:2020-07-23 17:21:45 【问题描述】:

TLDR:我需要一种以编程方式禁用 android 10 手势导航的方法,以便它们在从侧面滑动时不会意外返回

背景故事:Android 10 引入了手势导航,而不是底部的按钮。因此,现在在启用了它的 Android 10 设备上,他们可以从屏幕的任一侧滑动返回并从底部滑动以导航主页或在应用程序之间导航。但是,我正在研究 AR 中的实现,并希望将屏幕锁定为纵向,但允许用户进入横向。

如果用户将手机切换为横向但活动被锁定为纵向,则返回手势导航现在是从顶部滑动,这是在全屏应用程序中访问状态栏的常用方式(这个是) 因此,如果用户习惯了 Android 导航,他们会不经意地返回并离开体验。

有人知道如何 a) 以编程方式禁用 Android 10 的手势导航(但用户如何返回/回家?)或 b) 知道如何在不需要您的活动的情况下更改手势的方向支持横向?

【问题讨论】:

你有没有想过这个问题?我试过 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) List excludeRects = new ArrayList();矩形可见矩形 = 新矩形(); v.getWindowVisibleDisplayFrame(visibleRect); excludeRects.add(visibleRect); getWindow().setSystemGestureExclusionRects(exclusionRects);并且它只防止屏幕底部的后退手势。我希望这没有被 Google 记录得那么差。 【参考方案1】:

以编程方式阻止手势非常容易,但您不能对两侧的整个边缘执行此操作。 所以你必须决定要禁用手势的屏幕部分?

代码如下:

在您的 Utils 类中定义此代码。

 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);

检查您的布局是否设置在要排除边缘 getures 的那个活动中,然后应用此代码。

 // '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);
   
 );

我们将排除矩形宽度添加到 16dp 以获取您可以根据自己的喜好更改的后退手势。

这里有一些注意事项:-

您不得阻止两个侧面手势。如果这样做,那将是最糟糕的用户体验。 “getScreenHeight(activity)”是矩形的高度,所以如果你想在屏幕的左侧和上半部分阻止手势,只需将其替换为 getScreenHeight(activity)/2 new Rect() 中的第一个参数是 0,因为我们想要手势在左侧,如果你想要它在右侧,那么只需输入 - “getScreenWidth(activity) - SystemUtil.dpToPx(activity, 16)”

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

【讨论】:

【参考方案2】:

对于选项AB 并不是真正的答案。但至少用户在从侧面滑动时不会意外返回。

因此,如果设备是 Android 10 并且用户执行go back,那么如果用户真的想返回或不想返回,我会创建AlertDialog。虽然也会显示提示,但即使他们没有激活gesture navigation(仍然使用 2 或 3 按钮导航)。

@Override
public void onBackPressed() 
    if(android.os.Build.VERSION.SDK_INT >= 29)  //as long as the Device is Android 10 (API level 29) 
        // idk, need more condition like gestureNavigation.isActive()
        AlertDialog.Builder builder = new AlertDialog.Builder(YourActivity.this);


        builder
            .setMessage("Are you sure want to exit?")
            .setPositiveButton("Yes, let me out",  new DialogInterface.OnClickListener() 
                @Override
                public void onClick(DialogInterface dialog,int id) 
                    YourActivity.super.onBackPressed();
                
            )
            .setNegativeButton("No, wrong swipe/click", new DialogInterface.OnClickListener() 
                @Override
                public void onClick(DialogInterface dialog, int id) 
                    dialog.cancel();
                
            )
            .show();
     else 
        super.onBackPressed();
    

将此视为替代的最后手段。希望对你有帮助

【讨论】:

以上是关于Android 10 手势导航禁用的主要内容,如果未能解决你的问题,请参考以下文章

Android 13 返回导航大变更:返回键彻底废弃 + 可预见型返回手势

Android 13 返回导航大变更:返回键彻底废弃 + 可预见型返回手势

如何使 Android BottomSheetDialogFragment 出现在系统/手势栏后面?

android P/Q/R/S 9/10/11/12多任务手势动画OtherActivityInputConsumer情况-第一节

Android 手势导航(Launcher3 部分)

深入分析 Android 系统返回手势的实现原理