Reputation: 3595
My app's main interface is a viewpager where the user just slides the pages horizontally to get to the various pages. One of the pages has a google mapview (pasted below). My problem is that if the user is on the map page and uses a horizontal slide gesture, the page slides to the next page instead of the map moving sideways. It's as if the viewpager is getting the gesture before the map.
If the user is clever and begins sliding the map in a diagonal or vertical direction the map begins moving and then the gesture can continue horizontally. But I would prefer the map move instead of the page on a simple horizontal slide gesture. The page can always be slid using the textview.
Is there any way I can make this happen?
thanks,
Gary
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ContentPanel"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tvMAP"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Map"
style="@style/bigtype" />
<com.google.android.maps.MapView
android:id="@+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:apiKey="mykeygoeshere"
android:clickable="true" />
</LinearLayout>
Upvotes: 22
Views: 8114
Reputation: 165
for ViewPager2, you can solve this issue by creating a custom view that extends, google's mapView. and override the dispatchTouchEvent method. The code should be as below
class CustomMapView: MapView {
private var dontIntercepMove = false
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
when (ev?.action) {
MotionEvent.ACTION_DOWN -> dontIntercepMove = ev.x < LEFT_SCROLL_OFFSET * width || ev.x > RIGHT_SCROLL_OFFSET * width
MotionEvent.ACTION_MOVE -> if (!dontIntercepMove && parent != null) parent.requestDisallowInterceptTouchEvent(true)
}
return super.dispatchTouchEvent(ev)
}
}
This will allow the mapview to scroll when you swipe on it.. and when you swipe on the edges the viewpager will work
Upvotes: 0
Reputation: 11555
If using Google Maps V2, use
scrollingView.getClass().getPackage().getName().startsWith("maps.") in canScroll method:
@Override
protected boolean canScroll(View scrollingView, boolean checkV, int dx, int x, int y) {
if (scrollingView.getClass().getPackage().getName().startsWith("maps.")) {
return true;
}
return super.canScroll(scrollingView, checkV, dx, x, y);
}
Becase scrollingView is maps.j.b when using maps v2.
Also in my code, these classes are used:
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
Upvotes: 11
Reputation: 3450
Of course there is:
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
if(v instanceof MapView){
return true;
}
return super.canScroll(v, checkV, dx, x, y);
}
}
This will make the map ignore all the slides inside the map and just care about the slides/draggs outside the map. Hope it helps. (I do this right now for a webview with horizontal scroll)
EDIT: Forgot to mention that instead of the ViewPager you need to use the CustomViewPager in yout layout.
<com.yourpackage.CustomViewPager
android:id="@+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
Upvotes: 48