2012-12-06 21 views
53

私は新しいMapFragmentのいずれかをScrollViewに持っています。実際はSupportMapFragmentですが、とにかくです。それは動作しますが、2つの問題があります:ScrollViewのMapFragment

  1. スクロールすると、黒いマスクが残されます。黒は+/- ズームボタンがあった穴を除き、マップがあった場所を正確にカバーします。下のスクリーンショットを参照してください。これはAndroid 4.0にあります。ユーザーがScrollViewインターセプトタッチを防ぐために、マップと相互作用し、あなたがマップ内に垂直にパンしようとすると、それだけ含むScrollViewをスクロールしたときに

  2. ビューはrequestDisallowInterceptTouchEvent()を使用していません。私は理論的にはビュークラスMapViewを派生させ、その機能を追加することができましたが、MapFragmentは標準のものの代わりにMapViewをカスタマイズして使用することができますか? MapViewのフラグメントの上に透明画像を適用

Partial screenshot of scrolling issue

+1

"私はScrollViewに新しいMapFragmentsの1つを持っています" - これがうまくいくならば驚くでしょう。 「MapFragmentに、標準のMapViewを使用する代わりに、カスタマイズしたMapViewを使用するにはどうすればよいですか?」 - あなたはできません、AFAIK。 'MapView'をホストするための独自のフラグメントを作成する必要があります。 – CommonsWare

+0

私も同じ問題に直面していますが、フラグメント内で生のMapViewを使用しています。 ScrollViewまたはViewPagerでスクロールするときに黒いマスクが残っているのと同じ問題です。 –

+0

Nexus S(Android 4.1.2)では、この問題は発生していません。しかし、私がテストしたすべてのAndroid 2.2-2.3デバイスで、まったく同じ問題が発生しています。 – Ralf

答えて

52

問題を解決しているようです。それは一番美しいものではありませんが、うまくいくようです。ここではこれを示して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を使用し、透明のためにアンドロイド:背景= "android:color/transparent"でプレーンな '' – Ralf

+1

ありがとう、私はとても多くの仕事をしていないが、あなたのことをシンプルで偉大なものと呼んでいる。 – appukrb

+2

偉大な仕事の男:) @あなたもラルフ! –

8

これはおそらく、同じ場所で、そのルーツは、this questionで問題が発生しました。解決策は透明なフレームを使用することです。透明なフレームより軽い重さです。

0

質問の2番目の部分については、SupportMapFragmentからフラグメントクラスを派生させ、代わりにレイアウトで使用することができます。その後、Fragment#onCreateViewをオーバーライドしてカスタムMapViewをインスタンス化できます。

これでうまくいかない場合は、いつでも独自のフラグメントを作成できます。すべてのライフサイクルメソッドを自分で呼び出す必要があります(onCreate、onResumeなど)。 This answerにはもう少し詳細があります。

32

透明なImageViewを追加しても、黒いマスクを完全に取り除くことはできませんでした。地図の上部と下部にはスクロール中に黒いマスクが表示されました。

そのため、私はthis answerに小さな変化を見出しました。 それは垂直scrollviewだったので、私は、私の地図の断片に

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

を追加しました。私は私のメインScrollViewのためrequestDisallowInterceptTouchEvent(true)を設定し、質問の後半部分を解決するために

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

:だから、私のレイアウトは今、このように見えました。ユーザーがトランスペアレントイメージにタッチして移動したときに、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> 

コンテナクラス:

R & Dの多くの後に行わ
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

<?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クラス:

fragment_one.xmlがどのように見えるはずですFragmentOne.jの

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

は魅力のように機能し、一番投票された答えが私の場合には失敗したときに助けました。 –

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と透明レイアウトファイルに苦労する必要はありません:AVAは次のようになります。単にGoogleマップの軽いバージョンを使用して、問題が解決されます。

map:liteMode="true" 

上記のプロパティをレイアウトファイル内のマップフラグメントに追加します。問題は修正されます。