2012-12-06 39 views
53

我在ScrollView中有一個新的MapFragment s。其實這是一個SupportMapFragment,但無論如何。它有效,但有兩個問題:ScrollView中的MapFragment

  1. 當滾動時,它會在後面留下黑色掩碼。黑色正好覆蓋了地圖所在的區域,除了+/-縮放按鈕所在的孔外。見下面的截圖。這是在Android 4.0上。

  2. 當用戶與地圖,以防止ScrollView攔截觸摸交互的視圖不使用requestDisallowInterceptTouchEvent(),因此,如果您嘗試在地圖上垂直平移,它只是滾動含ScrollView。我理論上可以派生出一個視圖類MapView並添加該功能,但是如何才能讓MapFragment使用我的自定義MapView而不是標準的?

Partial screenshot of scrolling issue

+1

「我有一個滾動型新MapFragments之一」 - 我會感到驚訝,如果這個效果很好。 「我怎樣才能讓MapFragment使用我自定義的MapView而不是標準的?」 - 你不能,AFAIK。你將不得不創建自己的片段來託管你的'MapView'。 – CommonsWare

+0

我也面臨同樣的問題,但我在片段中使用原始MapView。同樣的問題,當在ScrollView或ViewPager中滾動時,黑色面具被留下。 –

+0

在我的Nexus S(Android 4.1.2)上,我沒有收到這個問題。不過,在我測試過的所有Android 2.2-2.3設備上,我遇到了完全相同的問題。 – Ralf

回答

52

應用在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> 
+4

我可以證實,這工作(雖然屏幕的某些部分仍然閃爍我結束了使用的FrameLayout作爲父母,和一個普通的''與'機器人:背景=「@機器人:彩色/透明」'用於透明視圖。 – Ralf

+1

感謝花花公子我是指很多沒有工作,但你的簡單和偉大的 – appukrb

+2

非常出色的人:) @Ralf你呢! –

8

這可能有其在同一個地方的根在導致問題this question。解決方案是使用透明框架,比透明圖像輕一點。

0

對於問題的第二部分 - 您可以從SupportMapFragment派生一個片段類,然後在您的佈局中使用它。然後,您可以覆蓋Fragment#onCreateView,並在那裏實例化您的自定義MapView。

如果不工作,你總是可以創建自己的片段 - 那麼你只需要採取調用所有的生命週期方法自己(的onCreate,的onResume等)的照顧。 This answer有更多的細節。

32

對於我來說,添加一個透明的ImageView並不能幫助完全去除黑色遮罩。地圖的頂部和底部仍然顯示滾動時的黑色遮罩。

所以對於它的解決方案,我發現在this answer有一個小的變化。 我說,

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> 

爲了解決我爲我的主滾動型設置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; 
     } 
    } 
}); 

這對我有效。希望它可以幫助你..

+0

是與標記點擊? –

+1

@Abdul Wahab:是的。我這樣設置,我可以點擊地圖上的標記。 – Simulant

+0

感謝親愛的,樂於助人的 –

2

我用這個結構,我克服了這個問題。

我用於映射片段的容器圖。

<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); 
    } 

} 
3

大量的R & d後完成:

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.j AVA的樣子:

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; 
       } 
      } 
     }); 
+0

我增加了坐在嵌套窗口小部件結構中的複雜性。但我終於找到了解決方案。 (我的滾動視圖只是通過view.getParent()可達) – Spidfire

+1

作品般的魅力,讓我當上最投票回答我你case..thank失敗。 –

0
<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> 
0

無需與customScrollViews和透明的佈局文件鬥爭。只需使用谷歌地圖的較輕版本,您的問題將得到解決。

map:liteMode="true" 

將上面的屬性添加到佈局文件中的地圖片段中。問題將得到解決。