MapView inside a ScrollView?

前端 未结 9 1222
时光取名叫无心
时光取名叫无心 2020-11-28 04:18

I would like to have a MapView inside a ScrollView, however when I try to scroll the map, the ScrollView takes priority! Is there a way to give the MapView priority when scr

相关标签:
9条回答
  • 2020-11-28 04:35

    A better/simpler way to do this without manipulating individual touch events. This will work if you are using MapView:

      @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            /**
             * Request all parents to relinquish the touch events
             */
            getParent().requestDisallowInterceptTouchEvent(true);
            return super.dispatchTouchEvent(ev);
        }
    

    Full class:

    public class CustomMapView extends MapView {
    
        public CustomMapView(Context context) {
            super(context);
        }
    
        public CustomMapView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomMapView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public CustomMapView(Context context, GoogleMapOptions options) {
            super(context, options);
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            /**
             * Request all parents to relinquish the touch events
             */
            getParent().requestDisallowInterceptTouchEvent(true);
            return super.dispatchTouchEvent(ev);
        }
    }
    

    If you are using a MapFragment then you can put the fragment in a Custom View, and in the dispatchTouchEvent() make the requestDisallowInterceptTouchEvent call.

    0 讨论(0)
  • 2020-11-28 04:38

    You can create a custom MapView like this:

    public class CustomMapView extends MapView {
    
        private MapFragment.ControlLock mCallbackControl;
    
        public CustomMapView(Context context) {
            this(context, null);
        }
    
        public CustomMapView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public CustomMapView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public CustomMapView(Context context, GoogleMapOptions options) {
            super(context, options);
        }
    
        public void setCallback(MapFragment.ControlLock callbackControl) {
            this.mCallbackControl = callbackControl;
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent event) {
    
            switch (event.getAction()) {
                case MotionEvent.ACTION_UP:
                    System.out.println("unlocked");
                    mCallbackControl.unlock(); /* Interface */
                    break;
                case MotionEvent.ACTION_DOWN:
                    System.out.println("locked");
                    mCallbackControl.lock(); /* Interface */
                    break;
            }
    
            return super.dispatchTouchEvent(event);
        }
    }
    
    0 讨论(0)
  • 2020-11-28 04:41

    I've tried with overriding MapView.onTouchEvent(...), but it didn't work for me. Here is code which works well (overriding MapView.onInterceptTouchEvent(...)):

    public class MyMapView extends MapView {
        private ViewParent mViewParent;
    
    //add constructors here
    
        public void setViewParent(@Nullable final ViewParent viewParent) { //any ViewGroup
                mViewParent = viewParent;
        }
    
        @Override
            public boolean onInterceptTouchEvent(final MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        if (null == mViewParent) {
                            getParent().requestDisallowInterceptTouchEvent(true);
                        } else {
                            mViewParent.requestDisallowInterceptTouchEvent(true);
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        if (null == mViewParent) {
                            getParent().requestDisallowInterceptTouchEvent(false);
                        } else {
                            mViewParent.requestDisallowInterceptTouchEvent(false);
                        }
                        break;
                    default:
                        break;
                }
    
                return super.onInterceptTouchEvent(event);
            }
    }
    
    0 讨论(0)
  • 2020-11-28 04:42

    If somebody wants this class in kotlin.
    I used dispatchTouchEvent like suggested by @rotem

    class CustomMapView : MapView {
               constructor(context: Context):
                super(context)
        constructor(context: Context, googleMapOptions: GoogleMapOptions):
                super(context, googleMapOptions)
        constructor(context: Context, attributeSet: AttributeSet):
                super(context, attributeSet)
        constructor(context: Context, attributeSet: AttributeSet, int: Int):
                super(context, attributeSet, int)
    
        override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
            Log.d("CustomWebView", "touchevent")
            when(event?.action) {
                MotionEvent.ACTION_UP -> {
                    Log.d("CustomWebView", "disallow Intercept")
                    parent.requestDisallowInterceptTouchEvent(false)
                }
                MotionEvent.ACTION_DOWN -> {
                    Log.d("CustomWebView", "allow Intercept")
                    parent.requestDisallowInterceptTouchEvent(true)
                }
            }
            return super.dispatchTouchEvent(event)
        }
    }
    
    0 讨论(0)
  • 2020-11-28 04:46

    For those who want the whole working code . here it is

    Custom map view class

    public class CustomMapView extends MapView {
    
    private ViewParent mViewParent;
    public CustomMapView(Context context) {
        super(context);
    }
    
    public CustomMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    public CustomMapView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    
    public CustomMapView(Context context, GoogleMapOptions options) {
        super(context, options);
    }
    
    public void setViewParent(@Nullable final ViewParent viewParent) { //any ViewGroup
        mViewParent = viewParent;
    }
    
    @Override
    public boolean onInterceptTouchEvent(final MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (null == mViewParent) {
                    getParent().requestDisallowInterceptTouchEvent(true);
                } else {
                    mViewParent.requestDisallowInterceptTouchEvent(true);
                }
                break;
            case MotionEvent.ACTION_UP:
                if (null == mViewParent) {
                    getParent().requestDisallowInterceptTouchEvent(false);
                } else {
                    mViewParent.requestDisallowInterceptTouchEvent(false);
                }
                break;
            default:
                break;
        }
    
        return super.onInterceptTouchEvent(event);
      }
    }
    

    Activity layout xml

      <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <location.to.your.CustomMapView
            android:id="@+id/mapView"
            android:layout_width="match_parent"
            android:layout_height="250dp"
             />
    
    </ScrollView>
    

    Instantiating the custom map class in your activity or fragment

           CustomMapView mapView = (CustomMapView) findViewById(R.id.mapView);
    

    That's it enjoy

    0 讨论(0)
  • 2020-11-28 04:48

    Make your own map and use it. It works fully for me.

    public class CustomMapView extends MapView {
    
    public CustomMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_UP:
            System.out.println("unlocked");
            this.getParent().requestDisallowInterceptTouchEvent(false);
            break;
        case MotionEvent.ACTION_DOWN:
            System.out.println("locked");
            this.getParent().requestDisallowInterceptTouchEvent(true);
            break;
        }
        return super.dispatchTouchEvent(ev);
    }} 
    

    In your layout xml,

    <com.yourpackage.xxxx.utils.CustomMapView
                    android:id="@+id/customMap"
                    android:layout_width="match_parent"
                    android:layout_height="400dp"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"
                    />
    
    0 讨论(0)
提交回复
热议问题