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