gpt4 book ai didi

android - ScaleGestureDetector 不适用于 ICS 及以下的 Fragment 或 ViewGroup 布局中的 View

转载 作者:搜寻专家 更新时间:2023-11-01 09:03:05 32 4
gpt4 key购买 nike

我的应用程序利用支持包来实现 Fragment s 2.2 向上。

我有一个 View使用 ZoomableView 的子类(我们称之为 ScaleGestureDetector )检测捏缩放事件。这是以熟悉的方式完成的;即在onTouchEvent()内, MotionEvent s 使用 mScaleDetector.onTouchEvent(event) 传递给检测器.一个 SimpleOnScaleGestureListener用于接收缩放事件。

ZoomableView class 始终显示为唯一 ViewFragment (我们称之为 ZoomableFragment )。应用程序中有两个用例。在一个用例中,布局仅包含 ZoomableFragment ,包含 ZoomableView .在第二个用例中,ZoomableFragment将与另一个 Fragment 一起显示。这个其他 Fragment碰巧住着一个MapView ,但使用 MapView与问题无关(如果第二个 Fragment 只包含一个普通的 View ,问题仍然存在)。

实际的问题是,在 Jellybean 之前的设备(特别是 Froyo 手机)上进行测试时,使用 Activity 时显示双胞胎- Fragment布局,ZoomableFragmentZoomableView ScaleGestureDetector不起作用。当我说“不起作用”时,我可以在调试器中看到它处理 MotionEvent s,但没有 SimpleOnScaleGestureListener 中的任何方法被称为。但是,当使用 Activity 时仅包含 ZoomableFragment ,尺度检测确实有效。如果我在 JellyBean 设备上试用该应用程序,双胞胎- Fragment情况绝对正常;即接收缩放手势。

我四处搜索,唯一能找到的问题是人们在哪里实现了 OnScaleGestureListener并通过从 onScaleBegin() 返回 false 来阻止它工作.这不是我的问题。

综上所述,ScaleGestureDetectorView 中使用时,它应该做的时候不调用它的监听器在多重支持 Fragment Froyo (Android 2.2) 上的布局,我假设包括 ICS。然而如果Fragment是屏幕上唯一的一个,探测器工作正常。此外,在我的 4.1+ Jellybean 设备上不存在任何问题。

编辑 1 在我的双 fragment 布局中,ZoomableFragment始终根据方向放置在右侧或底部。我刚刚做的一个有趣的观察是,如果我翻转布局使得 ZoomableFragment在纵向方向位于顶部(而不是下部 fragment ),或者在水平方向位于左侧,则比例检测器工作!因此,我怀疑这与 MotionEvent 的结果之间的关系有关。 getRawX()/getX() (和 Y 类似)方法,当使用 fragment 时。但是当我像这样翻转布局时,捏缩放不适用于相邻的 MapView Fragment !因此,总而言之,在 Froyo 上似乎 ScaleGestureDetector仅适用于 View包含在 Fragment 中在屏幕的 0,0 处有一个角。

编辑 2 在检查 ScaleGestureDetector 的来源后,我已经用一个简单的解决方案自己回答了这个问题。在 grepcode 上。因为来源甚至就 ICS 使用了 getRawX()/getRawY() ,我已经更新了这个问题,以说明 ICS 受到影响(我相信),而不仅仅是我最初想到的 Froyo。

编辑 3 我做了一个简单的测试,以完全消除与 Fragment 相关的任何事情。 s 或我的应用程序中的任何其他内容。我拿了简单的谷歌MapView示例项目并简单地更改了布局,以便大部分屏幕被 TextView 占据。 (重量 0.9)和一个很小的 ​​MapView位于底部,重量仅为 0.1。在我的 Froyo 设备上,它不会再捏缩放。在我的 JB 设备上,确实如此。所以看起来我并没有发疯,而且我遇到了 GestureScaleDetector 的问题。在 ICS 及以下(我认为 - 当然是 Froyo,无论如何),答案给出了解决方案。

最佳答案

从检查 ScaleGestureDetector grepcode 上的源代码,我看到 ScaleGestureDetector 的 Jellybean 版本不要使用 getRawX()getRawY() MotionEvent 的方法.但是,早期版本(Froyo、ICS 等)确实使用了 getRawX()getRawY()用于斜率计算。这就是问题所在,因为这意味着如果目标 View,比例检测器将无法工作。左上角没有接近 0,0。

我收到了 ScaleGestureDetector处理我的自定义 ZoomView ,即使将其放置在右侧或底部,只需在 onTouchEvent() 内执行此操作即可:

event.setLocation(event.getRawX(), event.getRawY());    
mScaleDetector.onTouchEvent(event);

这会导致 MotionEvent 的调整的内部偏移变量,使得 getX/YgetRawX/Y方法现在返回完全相同的值。这可以防止斜率计算失败。比例检测器当然适用于相对值,因此 X/Y 的绝对值无关紧要。如果您有更多依赖于绝对值的代码,您可以在之后执行我所做的操作来恢复它们:
    float originalY = event.getY();
float originalX = event.getX();
event.setLocation(event.getRawX(), event.getRawY());
mScaleDetector.onTouchEvent(event);
event.setLocation(originalX, originalY);

此外,如果我想放置我的 Fragment包含 MapView在底部或右侧,我已经在使用 MapView 的自定义子类无论如何,所以我只是添加了这个:
public boolean onTouchEvent(MotionEvent event) {

// Work around required for ScaleGestureDetector.
// Before calling the scale detector, perform a work-around that is needed for earlier APIs (I suspect
// ICS and below, judging from inspection of ScaleGestureDetector) to make the MotionEvent give the
// same values for getY / getRawY and getX / getRawX. Wildly different values, caused by the View
// being nowhere near the screen origin (i.e. the View is on the right or the bottom) means the
// detector doesn't work.

event.setLocation(event.getRawX() - getLeft(), event.getRawY() - getTop());
return super.onTouchEvent(event);
}

现在,我的 MapView无论在何处 Fragment 都会适本地缩放比例被放置。 (顺便说一句 - 这个问题完全不合时宜,但如果有人想知道,我将 MapView 放入 Fragment 中,成功地使用了 StackOverflow 上给出的 LocalActivityManager 解决方案)。 编辑 :实际上,有些事情并非 100% 正确: map 不会围绕捏合手势的中心进行缩放。我认为这与 getTop() 中未补偿 ActionBar/通知栏高度有关.

关于android - ScaleGestureDetector 不适用于 ICS 及以下的 Fragment 或 ViewGroup 布局中的 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13791904/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com