我使用的是ViewPager内部片段内的GoogleMap(V2 API)。 我在原来的问题是,ViewPager被捕获的所有水平滚动的姿势,所以如果用户在垂直或对角线方向开始了地图只能拖着。 所有水平拖动被抓获ViewPager
。 我发现,解决方案是创建派生ViewPager
类并覆盖canScroll
方法。 此视图拖传递给此方法,这样就可以使基于搜索的类型是一个决定。
就我而言,我的片段是一个SupportMapFragment
(从com.google.android.gms.maps
包),它给了我一个GoogleMap对象进行交互。 不过,我收到的ViewPager的实际控制canScroll
方法类型的maps.jb
。 我与我的自定义ViewPager类中下面的代码解决了这一问题。 不过,我不觉得这个类的名字舒适的检查的时候,我不知道这件事。 什么是maps.jb? 这是在运行时动态创建的类? 是否有可能为类型的框架,以后的更新变化? 鉴于只有查看的对象,有没有检查该阻力是由地图控件发起的更强大的方法吗?
@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);
}
这是在运行时动态创建的类?
这可能是一个ProGuard的重命名的输出。
是否有可能为类型的框架,以后的更新变化?
据我所知,是的。 我不知道,ProGuard的保证了名字将留之间架起相同。
请注意,这将取决于库项目。 当你拿上库项目的新版本,类名可能会改变。 但是,因为这是绑在自己的应用程序,在紧要关头,你可以与名游戏棒,并且只需要当你在图书馆项目的新版本修复了名。
话虽这么说,我同意基于名称匹配的是恶心。
鉴于只有查看的对象,有没有检查该阻力是由地图控件发起的更强大的方法吗?
好了,因为这不是一个MapView
,我们无法知道正是一个什么方式maps.jb
是。 我们知道这是不是一个MapView
,因为它没有命名MapView
,而谷歌(通过单独留在家中那名-keep
在ProGuard的配置指令,想必),所以我们可以从我们的应用程序使用它。
你可以尝试创建自己的MapFragment
用自己MapView
,看看是否有你得到一个MapView
,而不是maps.jb
(这可能是内部的一些子类MapView
所使用SupportMapFragment
)。 如果获得通过实际MapView
,那么你可以做直接的平等检查是否传入的对象是你的MapFragment
的MapView
。
或者,你可以看到,如果instanceof
说一个maps.jb
是一个MapView
。
无论这些都保证随着时间的推移可靠,无论是作为可以想象谷歌可能会改变的问题,使得MapView
被包裹的东西。 然而,我的猜测是,它更可能比生成的类名稳定。
maps.jb
继承自SurfaceView
。 因此,单程到半可靠地检测是否View
传递到canScroll()
是测试(v instanceof SurfaceView)
如果地图不V2别的东西后这失败(例如,扩展TextureView
在API级别11+),或者如果您ViewPager
网页有另一个SurfaceView
(如VideoView
)。
我已经申请上这个问题 ,试图让做出该决定加入地图API V2的一些稳定的手段。
首先,@Rich感谢分享您的解决方案 - 这是我一直在寻找。 我有延长SupportMapfragment是其项目之一的片段查看传呼机。 在我的解决方案我有一个自定义XML布局文件,因为我需要一些额外的按钮添加到片段。 这里是我的解决方案:
public class MapFragmentScrollOverrideViewPager extends ViewPager {
public MapFragmentScrollOverrideViewPager(Context context) {
super(context);
}
public MapFragmentScrollOverrideViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
if(v instanceof MapHoldingRelativeLayout) {
return true;
}
return super.canScroll(v, checkV, dx, x, y);
} }
public class MapHoldingRelativeLayout extends RelativeLayout {
public MapHoldingRelativeLayout(Context context) {
super(context);
}
public MapHoldingRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MapHoldingRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} }
片段布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="@+id/switchNearbyOffersButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="XXXX"
/>
<xxx.view.MapHoldingRelativeLayout
android:id="@+id/mapLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/switchNearbyOffersButton"
/>
</RelativeLayout>
片段本身:
public final class NearbyOffersFragment extends SupportMapFragment {
public static NearbyOffersFragment newInstance(String content) {
NearbyOffersFragment fragment = new NearbyOffersFragment();
return fragment;
}
private GoogleMap googleMap;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (googleMap == null) {
googleMap = getMap();
if (googleMap != null) {
setUpMap();
}
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_nearby_offers,
container, false);
final View mapFragmentLayout = super.onCreateView(inflater, container,
savedInstanceState);
MapHoldingRelativeLayout mapLayout = (MapHoldingRelativeLayout) rootView
.findViewById(R.id.mapLayout);
mapLayout.addView(mapFragmentLayout);
return rootView;
}
@Override
public void onResume() {
super.onResume();
setUpMapIfNeeded();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
private void setUpMap() {
googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
googleMap.getUiSettings().setZoomControlsEnabled(true);
googleMap.getUiSettings().setAllGesturesEnabled(true);
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(41.474856, -88.056928))
.zoom(14.5f)
.build();
googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
}
由于原SupportMapFragment的布局是我的自定义RelativeLyout你可以使用instanceof运算符,而不是直接引用maps.jb类的内...
希望这有助于在一年后...在我的情况下,我忽略了查看对象解决了这个问题。 你可以做的是通知CustomViewPager使当前页面中包含的地图。
public class CustomViewPager extends ViewPager {
@Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
if (this.containsMap()) {
return true;
}
return super.canScroll(v, checkV, dx, x, y);
}
}
在我的情况containsMap()只检查当前页面对应于一个预定义的页面索引:
public boolean containsMap(){
return getCurrentItem() == MAP_PAGE;
}
但它可能是更复杂的:添加一个名为setCanScrollIndex(INT指数,布尔canScroll)方法,以保持一个包含地图这些页面的引用。 从你的活动把它适当的时候。