(为长度道歉,我正在努力全面描述…)
我的Android应用程序同时显示多个视图。视图涉及图像的矩阵旋转和其他计算密集型任务,因此它们由一个单独的线程创建和管理,以减少UI线程的工作量。当更新后的视图准备就绪时,它会被传输到UI线程,UI线程会执行removeViewAt()和addView()来更新屏幕显示,从而确保只有UI线程接触到实际的用户界面。这种方法还从显示的视图的细节中完全抽象了UI线程和代码。。。它们只是要显示在屏幕上的"对象",每个对象都可以独立于其他对象进行更新,等等。这一切都很好,CPU负载很低,等等。
挑战来自于处理触摸事件。一个活动视图与其相应的onTouchListener()相关联,它运行良好。当要更新该视图时,它的替换将被组成,并与同一个onTouchListener()关联。移除/添加过程将它们交换出去,一切都很好,除了。。。。
如果当前视图被新视图替换时处于触摸事件的"中间"(已发生ACTION_DOWN),则两个视图都不会接收到关联的ACTION_UP。当旧视图被删除时,共享的onTouchListener()确实会收到ACTION_CANCELLED,但仅此而已。旧视图不活动以"看到"手指释放,而新视图在触摸开始时也不活动,因此它也不会对释放做出反应。
这有一些有趣的结果。首先,如果更新速度快于长点击超时,那么"长点击"就不可能了。您不能使用onClick。。。方法,因为这些方法在RELEASE时执行操作,您可能永远看不到发布。可以对初始触摸采取动作(而不是释放),但不能执行更高阶的触摸操作。
我考虑过用大小相同的透明视图覆盖视图,让长期覆盖的视图捕捉触摸事件,而其下的短期视图会改变外观。但这意味着底层视图(按钮等)上的任何小部件都无法处理自己的触摸事件。。。我将不得不编写新的代码来重新创建所有这些功能。
另一种方法是通过消除UI代码和View代码之间的抽象,使UI代码变得更加复杂。与其让UI代码将视图视为不透明对象,它还必须"了解"它们的内部细节,并能够智能地管理组成视图的各个组件。从本质上讲,视图组合的功能将在线程上下文中进行划分。我急切地不想放弃UI代码的抽象,因为它是一个非常干净的体系结构,使维护更加容易。但如果它不起作用,它有多棒也没关系!
所以。。。这里有明显的答案吗?其他人遇到过更改视图导致触摸事件丢失/中断的情况吗?你是怎么解决的?
谢谢!
是否可以更新内容而不是替换视图?或者这会对代码造成太大的改变吗?否则,您可以将导致问题的所有视图放置在每个视图的ViewGroup中。视图本身会被更改,但ViewGroup不会被更改。ViewGroup将接收触摸事件。这里的缺点是,你最终会在屏幕上看到更多的视图和内存中的对象。我希望这些建议对你有帮助。