Technically, placing a map view inside a ScrollView layout container can make the map becoming difficult to scroll. This is because the scrollable layout container will intercept the touch event so the map will lose the touch event, making it difficult to scroll or pan. This happens either on Android Map V2 or the previous versions.
In this case, i work with the SupportMapFragment in Android Map V2 so the workaround is to make a custom SupportMapFragment class so we can override its touch event. This solution is based on gaucho’s answer on related post in stackoverflow with some small changes made by me.
WorkaroundMapFragment.java
package net.londatiga.android.ui.fragment; import android.content.Context; import android.os.Bundle; import android.widget.FrameLayout; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import com.google.android.gms.maps.SupportMapFragment; public class WorkaroundMapFragment extends SupportMapFragment { private OnTouchListener mListener; @Override public View onCreateView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle savedInstance) { View layout = super.onCreateView(layoutInflater, viewGroup, savedInstance); TouchableWrapper frameLayout = new TouchableWrapper(getActivity()); frameLayout.setBackgroundColor(getResources().getColor(android.R.color.transparent)); ((ViewGroup) layout).addView(frameLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); return layout; } public void setListener(OnTouchListener listener) { mListener = listener; } public interface OnTouchListener { public abstract void onTouch(); } public class TouchableWrapper extends FrameLayout { public TouchableWrapper(Context context) { super(context); } @Override public boolean dispatchTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mListener.onTouch(); break; case MotionEvent.ACTION_UP: mListener.onTouch(); break; } return super.dispatchTouchEvent(event); } } }
In this class, we intercept the touch event by using TouchableWrapper class that extends the FrameLayout. There is also a custom listener OnTouchListener to dispatch the touch event to the main activity MyMapActivity that handles the map. When touch event occured, dispatchTouchEvent will be called and the listener mListener will handle it.
The ScrollView layout container, fragment_my_map.xml
<?xml version="1.0" encoding="UTF-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/sv_container" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- other child views //--> <fragment android:tag="fragment_map" android:id="@+id/fragment_map" android:layout_width="match_parent" android:layout_height="175dp" android:layout_marginTop="@dimen/activity_horizontal_margin" class="net.londatiga.android.ui.fragment.WorkaroundMapFragment"/> </ScrollView>
Inside map activity that uses the map, MyMapActivty.java
package net.londatiga.android.ui; import net.londatiga.android.ui.fragment.WorkaroundMapFragment; import com.google.android.gms.maps.GoogleMap; import android.widget.ScrollView; public class MyMapActivty extends MapActivity { private ScrollView mScrollView; private GoogleMap mMap; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_my_map); mMap = ((WorkaroundMapFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_map)).getMap(); mScrollView = (ScrollView) findViewById(R.id.sv_container); ((WorkaroundMapFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_map)).setListener(new WorkaroundMapFragment.OnTouchListener() { @Override public void onTouch() { mScrollView.requestDisallowInterceptTouchEvent(true); } }); } }
Inside activity class, get the GoogleMap mMap and ScrollView container mScollView then set the OnTouchListener to the WorkaroundMapFragment. When touch event occured, onTouch handler will be called and we block the event being dispatched the ScrollView layout. This will make the map scrollable without the ScrollView being scrollable too.
[ad#ad-720×90]







Works like a charm!
Above code is working good but one another problem arise google map controller inner ZoomIn,ZoomOut(+,-) sign not working when click
It’s possible to have this project? My project doesn’t work.
It’s working awesome…
You save my day
Thank you! That’s what i needed, it’s perfect.
Check out my blog. The following post includes a video that shows you how to create an Android smartphone application that displays a vertically scrolling list of countries on the screen. The application is created using the Eclipse IDE and Android SDK. It features an “OK” button at the bottom of the screen that, when pressed, terminates the application.
In the process of making this Android application you will encounter the following SDK object types, etc:
• ScrollView,
• Button,
• View,
• TableLayout,
• TableRow,
• OnClickListener,
• TextView,
• Colours in Android represented by hexadecimal numbers.
http://androidprogrammeringcorner.blogspot.com/2015/03/pak-longs-android-programming-corner.html
Best regards,
Philip
Where is source code
Thanks 🙂
Working perfect , you save my time 😀
Nice solution, clean and works perfectly!
What happens if we are using fragment instead of activity? This code below does not work since fragment forces you to use child fragment manager?
mMap = ((WorkaroundMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMapAsync(this);