Posted at

AndroidのScrollView内でMapを利用する方法

More than 3 years have passed since last update.

ScrollViewの中に地図を配置したときに、地図のスクロールや拡大・縮小をしようとすると、ScrollViewが反応してしまい、うまく操作できません。

これは、地図の親にあたるScrollViewによって、地図のタッチイベントが妨害されていることが原因です。

そこで、地図のタッチイベントが発生するごとに、ScrollView#requestDisallowInterceptTouchEvent()にtrueを設定して、ScrollViewが地図のタッチイベントを妨害しないようにします。

また、MapFragment自体にはタッチイベントを設定することができないため、別途タッチイベントを設定する用のFrameLayoutを作成し、これをMapFragmentに追加します。

実装は下記のようになります。


MapFragmentの拡張

public class MyMapFragment extends MapFragment {

private ScrollView parentScrollView = null;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = super.onCreateView(inflater, container, savedInstanceState);

TouchableWrapper frameLayout = new TouchableWrapper(this.getActivity());
((ViewGroup)layout).addView(frameLayout);

return layout;
}

public void setParentScrollView(ScrollView scrollView) {
this.parentScrollView = scrollView;
}

private class TouchableWrapper extends FrameLayout {

public TouchableWrapper(Context context) {
super(context);
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
if(parentScrollView != null) {
parentScrollView.requestDisallowInterceptTouchEvent(true);
}
break;
}
return super.dispatchTouchEvent(ev);
}
}

}


地図を表示する箇所で、拡張したMapFragmentに親のScrollViewを設定します。

FragmentManager manager = this.getFragmentManager();

MyMapFragment mapFragment = (MyMapFragment) manager.findFragmentById(R.id.map);
ScrollView scrollView = (ScrollView)view.findViewById(R.id.scrollView);
mapFragment.setParentScrollView(scrollView);

参考: http://www.londatiga.net/it/programming/android/how-to-make-android-map-scrollable-inside-a-scrollview-layout/