Google Maps API v2 SupportMapFragment inside ScrollView - users cannot scroll the map vertically

后端 未结 9 940
深忆病人
深忆病人 2020-11-27 13:01

I am trying to put a Google map inside a scroll view, so that the user can scroll down other contents to see the map. The problem is that this scroll view is eating up all t

相关标签:
9条回答
  • 2020-11-27 14:02

    The accepted answer did not work in my case. The Guest's answer did neither (but almost). If this is the case for someone else try this edited version of the Guest's answer.

    I have commented out the action bar height if someone needs to use it when calculating the hitbox.

    public class InterceptableScrollView extends ScrollView {
    
        List<View> mInterceptScrollViews = new ArrayList<View>();
    
        public InterceptableScrollView(Context context) {
            super(context);
        }
    
        public InterceptableScrollView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public InterceptableScrollView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public void addInterceptScrollView(View view) {
            mInterceptScrollViews.add(view);
        }
    
        public void removeInterceptScrollView(View view) {
            mInterceptScrollViews.remove(view);
        }
    
        private int getRelativeTop(View myView) {
            if (myView.getParent() == this)
                return myView.getTop();
            else
                return myView.getTop() + getRelativeTop((View) myView.getParent());
        }
        private int getRelativeLeft(View myView) {
            if (myView.getParent() == this)
                return myView.getLeft();
            else
                return myView.getLeft() + getRelativeLeft((View) myView.getParent());
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {
    
            // check if we have any views that should use their own scrolling
            if (mInterceptScrollViews.size() > 0) {
                int x = (int) event.getX();
                int y = (int) event.getY();
    
    
                /*
                int actionBarHeight = 0;
    
                TypedValue tv = new TypedValue();
                if (getContext().getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
                {
                    actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
                }
                */
    
                int viewLocationY = 0;
                int viewLocationX = 0;
                int relativeTop = 0;
                int relativeLeft = 0;
    
                for (View view : mInterceptScrollViews) {
    
                    relativeTop = getRelativeTop((View) view.getParent());
                    relativeLeft = getRelativeLeft((View) view.getParent());
                    viewLocationY = relativeTop - getScrollY();
                    viewLocationX = relativeLeft - getScrollX();
    
                    if (view.getHeight() + viewLocationY > y && y > viewLocationY && view.getWidth() + viewLocationX > x && x > viewLocationX)
                    {
                        return false;
                    }
                }
            }
    
            return super.onInterceptTouchEvent(event);
        }
    }
    
    0 讨论(0)
  • 2020-11-27 14:03

    Apply a transparent image over the mapview fragment.

    <RelativeLayout
        android:id="@+id/map_layout"
        android:layout_width="match_parent"
        android:layout_height="300dp">
    
        <fragment
            android:id="@+id/mapview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="-100dp"
            android:layout_marginBottom="-100dp"
            android:name="com.google.android.gms.maps.MapFragment"/>
    
        <ImageView
            android:id="@+id/transparent_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@color/transparent" />
    
    </RelativeLayout>   
    

    Then set requestDisallowInterceptTouchEvent(true) for the main ScrollView. When the user touches the transparent image and moves disable the touch on the transparent image for MotionEvent.ACTION_DOWN and MotionEvent.ACTION_MOVE so that map fragment can take Touch Events.

    ScrollView mainScrollView = (ScrollView) findViewById(R.id.main_scrollview);
    ImageView transparentImageView = (ImageView) findViewById(R.id.transparent_image);
    
    transparentImageView.setOnTouchListener(new View.OnTouchListener() {
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int action = event.getAction();
            switch (action) {
               case MotionEvent.ACTION_DOWN:
                    // Disallow ScrollView to intercept touch events.
                    mainScrollView.requestDisallowInterceptTouchEvent(true);
                    // Disable touch on transparent view
                    return false;
    
               case MotionEvent.ACTION_UP:
                    // Allow ScrollView to intercept touch events.
                    mainScrollView.requestDisallowInterceptTouchEvent(false);
                    return true;
    
               case MotionEvent.ACTION_MOVE:
                    mainScrollView.requestDisallowInterceptTouchEvent(true);
                    return false;
    
               default: 
                    return true;
            }   
        }
    });
    

    This worked for me. Hope it helps you..

    0 讨论(0)
  • 2020-11-27 14:08

    Most of the options listed above did not work for me but the following proved to be a great solution to the problem for me:

    Cheese Barons Solution

    I also had to implement is slightly differently for my implementation, as I am using the map in a fragment which made things slightly more complicated but easy to get working.

    0 讨论(0)
提交回复
热议问题