更新视图时丢失触摸事件

时间:2014-04-22 23:49:42

标签: android multithreading user-interface touch

(道歉,我试图充分描述事情......)

我的Android应用同时显示多个视图。视图涉及图像的矩阵旋转和其他计算密集型任务,因此它们由单独的线程创建和管理,以减少UI线程上的工作负载。当更新的View准备好后,它将被传输到UI线程,UI线程会执行removeViewAt()和addView()来更新屏幕显示,从而确保只有UI线程触及实际的用户界面。这种方法还完全从显示的视图的细节中抽象UI线程和代码......它们只是要在屏幕上显示的“对象”,每个都可以独立于其他对象进行更新,等等。这一切都很好,CPU负载低等等。

挑战来自处理触摸事件。活动视图与其相应的onTouchListener()相关联,该工作正常。当要更新该视图时,它的替换组成并且还与相同的onTouchListener()相关联。删除/添加进程将它们交换掉,一切都很好,除了....

如果当前视图在触摸事件的“中间”(已发生ACTION_DOWN)时被新视图替换,则两个视图都不会收到关联的ACTION_UP。删除旧视图时,共享的onTouchListener()确实会收到ACTION_CANCELLED,但就是这样。旧的View无法“看到”手指释放,并且当触摸开始时新的View不存在,因此它也不会对释放做出反应。

这有一些有趣的结果。首先,如果更新速率快于长时间点击超时,则“长按”变得不可能。出于同样的原因,您无法使用onClick ...方法,因为这些方法会在RELEASE上执行操作,您可能永远不会看到发布。可以对初始触摸(而不是释放)执行操作,但不能执行高阶触摸操作。

我已经考虑过使用相同大小的透明视图覆盖视图,让长寿命叠加层捕获触摸事件,而下面的短暂视图会改变外观。但这意味着底层视图(按钮等)上的任何小部件都无法处理自己的触摸事件......我将不得不编写新的代码来重新创建所有这些功能。

另一种方法是通过消除它与View代码之间的抽象来使UI代码更加复杂。它不必让UI代码将视图视为不透明对象,而是必须“了解”其内部细节,并能够智能地管理构成视图的各个组件。从本质上讲,View组合的功能将在线程上下文中划分。我焦急地不想放弃UI代码的抽象,因为它是一个非常干净的架构,使维护更容易。但是,如果它没有完成这项工作,那无关紧要!

那么......这里有任何明显的答案吗?其他任何人遇到改变视图导致触摸事件丢失/损坏的情况?你是怎么解决的?

谢谢!

1 个答案:

答案 0 :(得分:0)

您是否可以更新内容而不是替换视图?或者这会改变代码太多?否则,您可以将所有导致问题的视图放在ViewGroup中。视图本身已更改,但不是ViewGroup。 ViewGroup将是接收触摸事件的人。这里的缺点是你最终会在屏幕和内存中的对象上获得更多的视图。我希望这些建议对你有所帮助。