我在 ViewPager 内的 Fragment 内使用 GoogleMap (v2 api)。我遇到的最初问题是 ViewPager 正在捕获所有水平滚动手势,因此只有当用户从垂直或对角线方向开始时才能拖动 map 。 ViewPager
捕获所有水平拖动。我发现解决方案是创建一个派生的 ViewPager
类并覆盖 canScroll
方法。被拖动的 View 被传递给这个方法,所以你可以根据它是 View 的类型来做出决定。
在我的例子中,我的 Fragment 是一个 SupportMapFragment
(来自 com.google.android.gms.maps
包),它为我提供了一个要与之交互的 GoogleMap 对象。但是,我在 ViewPager 的 canScroll
方法中收到的实际控件是 maps.j.b
类型的。我已经在我的自定义 ViewPager 类中修复了以下代码的问题。但是,当我对此一无所知时,我不太愿意检查这个类名。什么是 maps.j.b?这是运行时动态创建的类吗?类型是否有可能在框架的 future 更新中改变?仅给定 View 对象,是否有更可靠的方法来检查拖动是否由 map 控件发起?
@Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
if(v.getClass().getName().equals("maps.j.b")) {
return true;
}
return super.canScroll(v, checkV, dx, x, y);
}
最佳答案
Is this a dynamically created class at runtime?
这可能是 ProGuard 重命名的输出。
Is it possible for the type to change in a future update of the framework?
据我所知,是的。我不知道 ProGuard 保证名称在构建之间保持不变。
请注意,这将取决于库项目。当您进行新版本的库项目时,类名可能会更改。但是,由于它与您自己的应用程序相关联,因此在紧要关头,您可以坚持使用名称游戏,并且只需要在处理新版本的库项目时修改名称即可。
话虽这么说,但我同意基于姓名的匹配很恶心。
Given only the View object, is there a more robust way of checking that the drag was initiated by a map control?
嗯,因为这不是 MapView
,我们无法知道 maps.j.b
到底是什么。我们知道它不是 MapView
,因为它没有命名为 MapView
,Google 保留了这个名称(通过 ProGuard 中的 -keep
指令)配置,大概)这样我们就可以在我们的应用程序中使用它。
您可以尝试使用您自己的 MapView
创建您自己的 MapFragment
并查看您是否获得了 MapView
而不是 maps.j.b
(可能是 SupportMapFragment
使用的 MapView
的一些内部子类)。如果您传递了实际的 MapView
,那么您可以直接进行相等性检查以查看传入的对象是否是您的 MapFragment
的 MapView
.罢工>
或者,您可以查看 instanceof
是否表示 maps.j.b
是 MapView
。
随着时间的推移,这些都不能保证可靠,因为可以想象谷歌可以改变事情,使 MapView
被包裹在某些东西中。但是,我的猜测是它比生成的类名更稳定。
maps.j.b
继承自 SurfaceView
。因此,一种半可靠地检测 View
是否传递到 canScroll()
的方法是测试 (v instanceof SurfaceView)
。如果 Maps V2 稍后执行其他操作(例如,在 API 级别 11+ 上扩展 TextureView
)或者如果您的 ViewPager
页面有另一个 SurfaceView
(例如,VideoView
)。
我已经提交了an issue on this尝试将一些稳定的方法添加到 Maps V2 API 中来做出此决定。
关于java - 自定义 ViewPager 以允许子 GoogleMap 控件水平滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14388494/