微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 AndroidAPI 级别 23+中绘制自定义 ViewGroup,并且在该 ViewGroup 之外仍然可以访问?

如何解决如何在 AndroidAPI 级别 23+中绘制自定义 ViewGroup,并且在该 ViewGroup 之外仍然可以访问?

我正在做一个项目,我主要需要做 4 件事:

  1. 获取屏幕源
  2. 找出用户点击了哪个按钮/文本/图片
  3. 围绕该对象绘制红色矩形。
  4. 重复

那么,到目前为止我所取得的成就。

  1. 为了获取屏幕源,我使用 AccessibilityService 覆盖 onAccessibilityEvent
  2. onAccessibilityEvent 我得到了关于绘制边界的信息。 (就像在 Rect 类中,topleftbottomright
  3. 我创建了扩展 ViewGroup
  4. 自定义视图
  5. 我重载了 onMeasureonDraw 方法

我成功地在按钮/文本/图像周围绘制了红色矩形,但不幸的是,我无法访问屏幕上的任何其他内容(即屏幕因我的视图而过载,我无法再点击屏幕)

我试过了:

  1. 使自定义视图的高度和宽度如此之小,以至于我认为它不会使整个屏幕过载。这个想法确实奏效了但是它不再是我想要的地方了。

这是我的 AccessibilityService 的元数据(xml 配置)

<?xml version="1.0" encoding="utf-8"?>


<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/app_name"
    android:accessibilityEventTypes="typeAllMask"
    android:packageNames="XX XXX" <!-- I've removed these for some purposes -->
    android:accessibilityFeedbackType="FeedbackAllMask"
    android:canRequestFilterKeyEvents="true"
    android:accessibilityFlags="flagIncludeNotImportantViews|flagRequestTouchExplorationMode|flagReportViewIds"
    android:notificationTimeout="100"
    android:canRetrieveWindowContent="true"
    android:canRequestTouchExplorationMode="true"
    android:canPerformGestures="true"
    android:canTakeScreenshot="true">

</accessibility-service>

这就是我技术上在屏幕上绘制东西的方式:

val drw = DrawingView(this)
val params = WindowManager.LayoutParams()
params.flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
params.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY
params.format = PixelFormat.TRANSLUCENT
val wm = getSystemService(WINDOW_SERVICE) as WindowManager
wm.addView(drw,params)

我也插入了图片

Pixel phone red box on nine

绘制这个红色框(矩形)后,整个屏幕无法访问

我想: 当我绘制红色矩形时,我希望其他按钮也可以访问,因为要删除当前的红色矩形并绘制一个新的...

想象一下这个应用类似于 TalkBack(Android 的集成无障碍服务)

解决方法

看起来您正在尝试调用 setAccessibilityFocusAppearance,它已添加到 Android S 中 - 所以这可能没有那么有用。

查看 AccessibilityService codelab,他们在不覆盖布局参数 type 字段的情况下添加他们的视图:

       // Create an overlay and display the action bar
       WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
       mLayout = new FrameLayout(this);
       WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
       lp.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
       lp.format = PixelFormat.TRANSLUCENT;
       lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // <--- here
       lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
       lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
       lp.gravity = Gravity.TOP;
       LayoutInflater inflater = LayoutInflater.from(this);
       inflater.inflate(R.layout.action_bar,mLayout);
       wm.addView(mLayout,lp);

所以我建议你尝试改变

    params.flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH

以下内容:

   params.flags = params.flags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。