MotionLayout 儿童拦截触摸事件的问题

2024-01-02

我的主布局中有一个根容器的 MotionLayout。里面还有其他的景色。其中之一是框架布局,包含一个片段。该片段是一个页面,由 NestedScrollView 等组成...... MotionLayout 具有仅水平滑动的 OnSwipe,而 NestedScrollView 应该只能垂直滚动。我必须扩展 MotionLayout onInterceptTouchEvent 方法(请查看下面的代码),并且只将那些非水平的触摸事件传递给子级。到目前为止非常简单it works.

问题是,当我start在吸收某种触摸事件的视图(如按钮或 NestedScrollView)上滑动,它会扰乱 MotionLayout 转换并立即跳过帧,因此锚点与我的鼠标位置相对应。转换几乎完全在一帧内进行,并且破坏了 UI 体验。我的猜测是,如果 MotionLayout 采用 X1 和 X2 进行转换,则 X1 值就是导致问题的值,并且它的值来自不应该出现的地方。当然,当我开始在触摸吸收元素上滑动时。

这是我的 customMotionLayout 的 OnInterceptTouchEvent 的重写方法:

 override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        super.onInterceptTouchEvent(event)

        return when (event.actionMasked) {
            MotionEvent.ACTION_DOWN -> {
                previousX = event.x.toInt()
                previousY = event.y.toInt()
                mIsScrolling = false
                false
            }
            MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
                mIsScrolling = false
                false
            }
            MotionEvent.ACTION_MOVE -> {
                if (mIsScrolling) true
                 else {
                    var xMotion: Int = abs(previousX - event.x.toInt())
                    var yMotion: Int = abs(previousY - event.y.toInt())
                    previousX = event.x.toInt()
                    previousY = event.y.toInt()
                    if (xMotion >= yMotion) {
                        mIsScrolling = true
                        true
                    } else false}}
            else -> {
                mIsScrolling = false
                false
            }
        }
    }

这是相关的转换:

    <Transition android:id="@+id/options_to_now" motion:motionInterpolator="easeInOut"
        motion:pathMotionArc="none"
        motion:constraintSetStart ="@id/options_state"
        motion:constraintSetEnd="@id/now_state"
        motion:duration="100">
        <OnSwipe
            motion:maxAcceleration="100"
            motion:maxVelocity="100"
            motion:dragDirection="dragRight"
            motion:touchAnchorId="@id/view_options"
            motion:touchAnchorSide="left"
            motion:touchRegionId="@id/view_options"/>
    </Transition>

我通过测试确保 MotionDescripton 和布局没有问题。

值得注意的是,当我不触摸吸收某种触摸事件的元素时,该动作可以完美地工作。就像我的布局中的空白区域一样,当我在这些元素上滑动时,它只会导致上述问题。

也许如果我知道 MotionLayout 过渡如何与 touchPositions 相关,我就可以修复它。

更新 1:我注意到,如果我单击空白区域(只需单击 ACTION_DOWN),然后滑动,即使从那些顽皮的元素开始,问题也会有所不同。该单击以某种方式更新了过渡的协调位置。它以我单击的位置为起点,例如 x1。然后,当我在吸收触摸事件的东西上滑动时,它会从那里获得 x2。现在我在下一帧中看到的结果就像我将运动从 x1 滑动到 x2 一样。

更新 2:我注意到的另一件事我认为与我的问题非常相关,那就是当我完成滑动时,转换始终处于 STARTED 状态。就像我从 x1 滑动到 x2 一样,它的状态从开始、完成然后开始。所以我猜当我的下一次滑动出现时,它认为我的手指一直在触摸上并且我手动地滑动,但我没有。当我在屏幕上没有手指的情况下完成一个完整的滑动手势循环并完成它时,听完转换并打印状态后日志中的结果如下。所以最后一个被调用的事件开始了,这对我来说不合逻辑。

D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.014359029
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.02863888
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.044761233
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.06311959
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.09285617
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.12685902
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.17269236
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.22314182
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.27269235
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.32545927
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.389359
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.4449254
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.44595188
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.4948284
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.57895637
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.6884479
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.814522
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.8918733
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.95612586
D/e: Changed, state = -1 / p1 = 2131230901 / p2 = 2131230907 / p3 = 0.9949746
D/e: Completed: state = 2131230907 / p1 = 2131230907
D/e: Started, state = 2131230907 / p1 = 2131230901 / p2 = 2131230907
    Changed, state = 2131230907 / p1 = 2131230901 / p2 = 2131230907 / p3 = 1.0

更新 3:我注意到的另一件事是,当且仅当转换成功更改运动状态时,我们会遇到这样一种情况:通过单击其中一个触摸吸收元素,motionLayout 不会收到 OnTouchEvent! (这就是我正在处理的有问题的行为存在的情况)以及如果我在应用程序启动时不刷任何东西(虽然没有问题)yet),通过单击按钮,我在 MotionLayout 中收到 ACTION_DOWN 和 ACTINO_UP。因此,在转换到新状态后,无论 MotionLayout 中发生什么,它都会阻止 MotionLayout 从子级接收 OnTouchEvents。

更新4:我不太熟悉MotionLayout如何处理场景创建,但如果有人知道,是否motionLayout会动态创建一个场景,从而以某种方式阻止onTouchEvent一路返回到父级?

更新5:因此,当motionLayout未接收到带有ACTION_DOWN的motionEvent时,就会出现问题。我查看了调用堆栈,认为它应该与视图吸收事件dispatchTouchEvent方法有关,当开始在触摸吸收元素上滑动时,ACTION_DOWN返回true,其他情况返回false。因此,在dispatchTouchEvent中返回true会导致motionLayout未接收到ACTION_DOWN并导致问题。在dispatchTouchEvent内部,区分两种情况结果的代码是:

  if (onFilterTouchEventForSecurity(event)) {
        ...
        if (!result && onTouchEvent(event)) {
             result = true;
        }
     }

例如,单击按钮时 OnTouchEvent(event) 返回 true,单击空白区域时返回 false。

我正在使用 2.0.0-beta4 版本的约束布局。


我想我找到了问题所在,是motionLayout的onInterceptTouchEvent中的mRegionView。在该方法中的某个地方,它检查事件 x 和 y 与 mRegoinView 的左、右、上、下的边界。我查看了这些值,发现在那些有问题的情况下,这些值有点奇怪,因此该函数返回 false 并且从不调用 MotionLayout 的 onTouch 事件。值为:

好情况 x 354 450 米 前 0 名 左 16 底部 1280 权利 752

糟糕的情况(如问题中所述,当 1 个转换已成功将状态更改为新状态并且我们开始拖动触摸吸收元素时)

x 300 450 米 前 0 名 剩下 750 底部 1280 右768

正如你所看到的,左边有 750,这对我来说有点奇怪,我不知道原因。我可能会检查为什么它具有该值并更新此答案,但现在我只是删除了motionLayout中onInterceptTouchEvent中的boundCheck,因为至少现在我没有真正使用特定区域。

更新:这是 touchRegion 和regionId。对于相同的场景和元素(比如说按钮),第一次单击它时,[在 touchProcess 中]它工作正常,但是如果您进行转换,那么它会在 touchProcess 中返回错误的视图,regionId 返回另一个视图视图,它是前一个过渡场景的父级。我不知道为什么会发生这种情况,或者是某种错误(考虑到这个库仍然是测试版,可以理解)。 所以我只是重写了 MotionLayout 的 touchProcess 并忽略了检查 TouchRegion 边界的部分。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MotionLayout 儿童拦截触摸事件的问题 的相关文章

  • 在 Android 模拟器上运行完整的 Android 手机 ROM

    正如标题所说 是否可以在 Android 模拟器中运行完整的 Android 设备 ROM 是的 你可以 但让它 100 工作可能很困难 大多数 ROM 都包含其运行硬件的特定驱动程序 我并不是 100 全力以赴 但可以尝试以下步骤 创建
  • Android Toast 消息不起作用

    我正在通过 Andengine 为 Android 开发游戏 我有 MainActivity 类和 GameScene 类 我在 GameActivity 中使用 Toast 消息 它正在发挥作用 Toast makeText this H
  • 在android Gridview中合并行和列

    我正在android中做一个图像查看页面 我需要在某些地方合并行 在某些地方合并列 我们可以在gridview中做到这一点吗 如果我们选择任何合并图像 则应选择整个图像视图 请任何人告诉我一个建议 提前致谢 Try 非对称网格视图 http
  • 具有自定义厚度的虚线分隔符

    我有一个虚线分隔符
  • Android 软键盘 - 禁用某些键

    我正在寻找一种使用内置软键盘并禁用某些键的方法 例如 如果用户不应该使用字母 f 因为在列表中该字母不存在 则该键应显示为灰色 想象一下 用户可以在文本框中键入文本以从列表中进行选择 该列表包含 ABC BCCD 床 如果用户输入 A 然后
  • Android:将图像裁剪为特定尺寸

    我的目的是让用户从图库中选择一张图像 然后进行裁剪活动 但是 我需要将定义裁剪蒙版的矩形锁定到某个尺寸 然后用户只需重新定位它即可显示图像的一部分 关于如何做到这一点有什么想法吗 Thanks T Intent intent new Int
  • Android 和 Honeycomb - 如何使用 SDK 13 拥有菜单图标而不需要“操作栏”

    我想最大限度地利用 Honeycomb 应用程序的屏幕 由于屏幕底部已经被 始终打开 的项目所困 我想在该空间中添加一个菜单按钮 而不是牺牲更多的屏幕空间 在顶部放置一个 操作栏 我怎样才能做到这一点without降级到 API 10 或更
  • RecyclerView 单击将数据传递到新活动

    我正在制作一个包含三个选项卡的应用程序 每个选项卡都有一个带有两个文本的 recyclerview 我希望用户能够单击任何 recyclerview 项目 并且该项目中的文本应传递到新活动 这是应用程序外观的图像 https i stack
  • “添加到 FragmentContainerView 的视图必须与 Fragment 关联”与 android 导航组件

    当导航组件切换到片段时 我收到 添加到 FragmentContainerView 的视图必须与片段关联 崩溃 这是什么原因造成的 我没有在任何地方看到提到这一点 并且花了一段时间才弄清楚 但在这种情况下 我试图在迁移到导航拱门组件时设置一
  • 如何在移动应用程序上连接到服务器?

    我是移动应用程序的新手 我基本上来自网络开发平台 我只是在玩 App Framework LungoJS Jquery Mobile kendo 等移动框架 以获得该垂直领域的一些知识 我正在开发的应用程序仍然处于 UI 级别 我所需要的只
  • Android 导航组件 - 从“任何地方”/基本片段导航?

    我正在开发一个应用程序 它有一个奇怪的花招 可以在设备旋转时打开特定的片段 在实现 android 的导航组件之前 所需要的只是对当前活动的引用 并且可以在特定时刻向用户显示的任何内容之上执行手动片段事务 但是在转移到导航组件之后 我发现很
  • Proguard 正在破坏我的清洁度。 Gson 和泛型

    我有一个从持久性加载信息的函数 我只是以一种非常简单的方式告诉它的类型 该类称为SharedPreferencesHelper kt所以它是一个真正的生活问题解决者 fun
  • Android Lollipop 中应用程序外部配置文件和内部配置文件之间的数据传输

    相关问题安卓工作版 我的应用程序是一个设备管理员特权应用程序 现在我修改了创建托管工作配置文件并将其自身设置为配置文件所有者的代码 问题是 如果我upgrade我的应用程序 它成为设备管理员的配置文件所有者 现在将会有两份我的应用程序 一个
  • java.lang.UnsatisfiedLinkError - android studio gradle 中的 NDK?

    文件夹结构 app main java jni Android mk Application mk hello jni c res 在构建 gradle apply plugin com android application androi
  • 以编程方式创建 FloatingActionButton(无需 xml)

    我很欣赏 Android 的 FloatingActionButton fab 功能 并希望在我的项目中的许多不同地方使用它们 现在 我有这样的东西 我有几个 xml 规范 除了 id 图标和 onclick 之外 所有这些规范都是相同的
  • 通过 Google 帐户从 Google Play 安装的应用程序列表

    以下是我的问题 是否可以通过使用任何 api 以编程方式通过 Google Play 获取用户已安装的应用程序列表 请注意 我并不是询问设备中当前安装的应用程序列表 而是询问在某个时刻已安装的应用程序列表 我需要解决上述问题 因为我正在考虑
  • Dart/Flutter 如何编译到 Android?

    我找不到任何具体的资源 Dart 是否被编译到 JVM 或者 Google 的团队是否编译了 Dart VM 以在 JVM 上运行 然后在 JVM 内的 Dart VM 中运行 Dart 前者更有意义 并且符合 无桥 的口号 但后者似乎更符
  • 我想要有条件的登录导航,没有 MAIN 片段或按钮

    我正在使用 Android Jetpack 导航组件 实时数据和 Firebase 我希望工作流程就像用户打开应用程序时一样 然后根据登录 注销状态导航到登录 配置文件片段 而不需要任何主片段或按钮 请 我的应用程序中没有主要片段 用户启动
  • 连接到具有相同 SSID 的最强接入点(信号最强的接入点)

    我正在编写一个程序来始终连接到最强的接入点 我的意思是信号最强的接入点 首先 我扫描所有可用的 WiFi 网络 然后限制它们仅查看具有相同 SSID 的网络 这样我就可以看到一个网络的所有AP 当我连接到该网络时 它没有连接到最强的信号 但
  • (Unity 中的 Firebase 数据库)在 Android 构建期间在 Temp 中缺少classes.jar

    I am using Firebase Database in my Unity project but I am having some issues when building the project for android It ru

随机推荐

  • 使用文本框输入在画布上移动对象

    我有一个画布 可以在上面添加图层 这些图层可以移动 选择 旋转 调整大小等 在画布下方 我显示图层的属性 x y 宽度 高度 我想做的是 当我更改包含 x 和 y 坐标的文本框中的值时 图层应该重新定位到我输入的坐标 我已经尝试了几件事 但
  • 在 Windows 中更改 Python 3 中的“区域设置首选编码”

    我正在使用 Python 3 最近从 Python 2 切换而来 我的代码通常在 Linux 上运行 但有时 不经常 在 Windows 上运行 根据 Python 3 文档open https docs python org 3 libr
  • 以编程方式单击时突出显示 TextView

    我动态生成 TextView 其工作方式类似于按钮 现在我想在他们受到压力时突出显示他们 比如更改文本颜色或背景颜色 我尝试过使用选择器 但它不起作用
  • 如何设置 PowerShell Cmdlet 的默认输出格式?

    我正在 C 中创建一个 PowerShell Cmdlet 以从 JSON 文件读取字段并输出一些对象 这些对象是简单的 POCO 类型 public class FieldDefinition public FieldDefinition
  • C#动态编译字符串和.cs文件

    我正在开发一个网站 用户可以在该网站上针对浏览器文本区域中的问题实现 C 代码解决方案并提交 然后 服务器将将该代码与我在服务器上提供的预定义接口一起编译 将其视为一种策略设计模式 我提供一个策略接口 由用户实现 所以我需要在运行时一起编译
  • 部分排序数组,最后 n 个元素已排序?

    有没有办法对数据数组执行部分排序 以便对最后 n 个元素进行排序 我的意思是使用标准库 而不是实现我自己的排序函数 这就是我现在正在做的事情 示例输出 使用较少的比较器 2 1 4 5 6 8 10 之后的元素 都大于之前的元素 但仅限于右
  • 共享一个控制器的角度多条路线

    我不确定我是否正确处理了这个问题 但我正在构建一个电子商务网站 该网站的一部分有 6 个不同的产品网格页面 每个页面都可以使用相同的视图 ul class products row li class product thumbnail co
  • ASP.NET / Web.config:customErrors 仅在 404 上重定向

    我有这样的场景 用户访问我的网站并点击不再存在的链接 他应该被重定向到自定义错误页面 这样可行 如果用户执行某些操作 引发错误 他应该看到堆栈跟踪和真正的错误页面 这是我当前的 Web config
  • 使用 PHP 文件功能在另一台服务器上创建文件

    我的一台服务器上有一个脚本 我希望该脚本使用 PHP 在我的另一台服务器上创建一个文件 而不是通过 FTP 有很多方法可以做到这一点 我自己会选择第一个 因为它最容易设置 如果你有PHP 另一台服务器上的Apache 只需使用以下命令调用另
  • 将 pfx 格式转换为 p12

    我需要导出一个 pfx将证书格式 来自 Windows MMC 转换为 p12在另一个应用程序中使用 我找不到办法做到这一点 任何人都可以建议一个方法吗 p12 and pfx都是 PKCS 12 文件 我错过了什么吗 您是否尝试过重命名导
  • 从父子表生成字符串树分支

    我有一个父子表 如下所示 child father H G F G G D E D A E B C C E 我希望 sql server 生成类似的东西 正如这个问题中所问的那样 将一系列父子关系转化为层次树 https stackover
  • Angular 2.x 在 body 标签上绑定类

    由于 Angular 2 x 是在主体内部引导的 我该如何添加 class fixed isFixed 在 body 标签上 在我的应用程序之外
  • 匹配不带引号的逗号的正则表达式

    我正在使用 Clojure 所以这是在 Java 正则表达式的上下文中 这是一个示例字符串 a ab cd efg b ab def egf c Conjecture 重要的位是每个字符串后面的逗号 我希望能够使用Java的replaceA
  • Go 中的简单工作池

    我正在尝试在 go 中实现一个简单的工作池 但不断遇到问题 我想做的就是让一定数量的工人先完成一定数量的工作 然后再做更多的工作 我正在使用的代码类似于 jobs make chan imageMessage 1 results make
  • 在 jquery 验证中实现 require_from_group

    我正在尝试获取一组输入来进行验证 因此 如果任何输入为空 它将在输入下方显示一条消息 我一直在关注另一个SO答案here https stackoverflow com a 2589646 571723 4 个输入将不会验证 当没有提交数据
  • SQL Server 2008 上 varbinary(max) 文件流的长度

    有没有一些有效的方法来获取 varbinary max filestream 列中的数据长度 我只找到了转换为 varchar 然后调用 LEN 函数的示例 SELECT length DATALENGTH Name Name FROM P
  • 如何在价格中添加尾随零?

    我有一个返回产品价格的脚本 但是 价格可能包含也可能不包含尾随零 所以有时我可能会258 22其他时候我可能有258 2 在后一种情况下 我需要添加尾随零 我该怎么做呢 你可以使用javascripttoFixed方法 source htt
  • 如何在fragment中设置setContentView

    我正在尝试在片段中调用库 但不知道如何在片段中设置它我已在主活动中完成它 但在片段中设置 setContentView 时出现错误 编译依赖 compile com github medyo android about page 1 0 2
  • Android Studio 图像资源启动器图标背景颜色

    我的应用程序有一个 png 徽标 它没有背景 当我将其作为图像资源添加到 android studio 时 我被迫有背景 十六进制字段不接受 8 位颜色代码 仅接受 6 位 有没有办法让背景不可见 要使背景透明 请设置shape as No
  • MotionLayout 儿童拦截触摸事件的问题

    我的主布局中有一个根容器的 MotionLayout 里面还有其他的景色 其中之一是框架布局 包含一个片段 该片段是一个页面 由 NestedScrollView 等组成 MotionLayout 具有仅水平滑动的 OnSwipe 而 Ne