ScrollView中的MapFragment

我在ScrollView有一个新的MapFragment 。 其实这是一个SupportMapFragment ,但无论如何。 它工作,但有两个问题:

  1. 滚动时,后面留下一个黑色的面具。 黑色正好覆盖了地图所在的区域,除了+/-缩放button所在的孔之外。 看下面的截图。 这是在Android 4.0上。

  2. 当用户与地图交互时,视图不会使用requestDisallowInterceptTouchEvent()来防止ScrollView拦截触摸,所以如果你试图在地图中垂直移动,它只是滚动包含ScrollView 。 我理论上可以派生一个视图类MapView并添加该function,但是如何让MapFragment使用我自定义的MapView而不是标准的MapView

滚动问题的部分截图

在mapview片段上应用透明图像似乎可以解决问题。 这不是最漂亮的,但它似乎工作。 这是一个显示这个的XML片段:

 <RelativeLayout android:id="@+id/relativeLayout1" android:layout_width="match_parent" android:layout_height="300dp" > <fragment android:id="@+id/map" android:name="com.google.android.gms.maps.MapFragment" android:layout_width="fill_parent" android:layout_height="fill_parent"/> <ImageView android:id="@+id/imageView123" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/temp_transparent" /> </RelativeLayout> 

对我来说,添加一个透明的ImageView并没有帮助完全去除黑色的面具。 地图的顶部和底部仍然显示滚动时的黑色面具。

所以解决scheme呢,我在这个答案中发现了一个小小的改变。 我补充说,

 android:layout_marginTop="-100dp" android:layout_marginBottom="-100dp" 

我的地图片段,因为它是垂直滚动视图。 所以我现在的布局是这样的:

 <RelativeLayout android:id="@+id/map_layout" android:layout_width="match_parent" android:layout_height="300dp"> <fragment android:id="@+id/mapview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="-100dp" android:layout_marginBottom="-100dp" android:name="com.google.android.gms.maps.MapFragment"/> <ImageView android:id="@+id/transparent_image" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@color/transparent" /> </RelativeLayout> 

为了解决问题的第二部分,我为主ScrollView设置了requestDisallowInterceptTouchEvent(true) 。 当用户触摸透明图像并移动时,我禁用了MotionEvent.ACTION_DOWNMotionEvent.ACTION_MOVE的透明图像上的触摸,以便地图片段可以使用触摸事件。

 ScrollView mainScrollView = (ScrollView) findViewById(R.id.main_scrollview); ImageView transparentImageView = (ImageView) findViewById(R.id.transparent_image); transparentImageView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: // Disallow ScrollView to intercept touch events. mainScrollView.requestDisallowInterceptTouchEvent(true); // Disable touch on transparent view return false; case MotionEvent.ACTION_UP: // Allow ScrollView to intercept touch events. mainScrollView.requestDisallowInterceptTouchEvent(false); return true; case MotionEvent.ACTION_MOVE: mainScrollView.requestDisallowInterceptTouchEvent(true); return false; default: return true; } } }); 

这对我有效。 希望它可以帮助你..

这大概就是在这个问题的根源上引起问题的 。 解决scheme是使用一个透明的框架,比透明的图像重量轻一点。

大量的研发工作完成后:

fragment_one.xml应该如下所示:

 <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/scrollViewParent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <RelativeLayout android:layout_width="match_parent" android:layout_height="400dip" > <com.google.android.gms.maps.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent" /> <View android:id="@+id/customView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@android:color/transparent" /> </RelativeLayout> <!-- Your other elements are here --> </LinearLayout> </ScrollView> 

你的Java类的FragmentOne.java看起来像:

 private GoogleMap mMap; private MapView mapView; private UiSettings mUiSettings; private View customView 

onCreateView

 mapView = (MapView) rootView.findViewById(R.id.mapView); mapView.onCreate(savedInstanceState); if (mapView != null) { mMap = mapView.getMap(); mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); mUiSettings = mMap.getUiSettings(); mMap.setMyLocationEnabled(true); mUiSettings.setCompassEnabled(true); mUiSettings.setMyLocationButtonEnabled(false); } scrollViewParent = (ScrollView)rootView.findViewById(R.id.scrollViewParent); customView = (View)rootView.findViewById(R.id.customView); customView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: // Disallow ScrollView to intercept touch events. scrollViewParent.requestDisallowInterceptTouchEvent(true); // Disable touch on transparent view return false; case MotionEvent.ACTION_UP: // Allow ScrollView to intercept touch events. scrollViewParent.requestDisallowInterceptTouchEvent(false); return true; case MotionEvent.ACTION_MOVE: scrollViewParent.requestDisallowInterceptTouchEvent(true); return false; default: return true; } } }); 

我用这个结构,我克服了这个问题。

我用地图片段的容器视图。

 <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:text="Another elements in scroll view1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <com.erolsoftware.views.MyMapFragmentContainer android:orientation="vertical" android:layout_width="match_parent" android:layout_height="250dp"> <fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/eventMap" tools:context="com.erolsoftware.eventapp.EventDetails" android:name="com.google.android.gms.maps.SupportMapFragment"/> </com.erolsoftware.views.MyMapFragmentContainer> <TextView android:text="Another elements in scroll view2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </ScrollView> 

容器类:

 public class MyMapFragmentContainer extends LinearLayout { @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { ViewParent p = getParent(); if (p != null) p.requestDisallowInterceptTouchEvent(true); } return false; } public MyMapFragmentContainer(Context context) { super(context); } public MyMapFragmentContainer(Context context, AttributeSet attrs) { super(context, attrs); } public MyMapFragmentContainer(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } } 

对于问题的第二部分 – 您可以从SupportMapFragment派生一个片段类,然后在您的布局中使用它。 然后,您可以覆盖Fragment#onCreateView ,并在那里实例化您的自定义MapView。

如果这不起作用,你总是可以创build自己的片段 – 那么你只需要照顾自己调用所有的生命周期方法(onCreate,onResume等)。 这个答案有更多的细节。

 <ScrollView android:layout_width="match_parent" :: :: :: <FrameLayout android:id="@+id/map_add_business_one_rl" android:layout_width="match_parent" android:layout_height="100dp" > <fragment android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="-100dp" android:layout_marginBottom="-100dp" /> </FrameLayout> :: :: :: </ScrollView>