ScrollView内的MapView?


74

我想在ScrollView中有一个MapView,但是当我尝试滚动地图时,ScrollView优先!在地图内滚动时,是否有办法赋予MapView优先级,否则,是否给ScrollView提供优先级?

谢谢!


你的布局是什么?您可以张贴最终渲染的屏幕截图吗?
Aman Alam

1
MapView自动处理滚动。...–
Sandy

2
我知道。我有一个ScrollView,其中包含许多不同的内容,包括MapView。问题是,当我尝试在mapview中滚动时,scrollview将覆盖它。
塞萨尔(Cesar)

我也在我的应用程序中这样做,但是没有任何解决方案,因此我将mapview放在滚动视图之外,并将其余布局放在scrollview中。
桑迪

1
其他答案没什么新奇的,但是我就如何解决这个问题建立了一个要点。gist.github.com/Sottti/890daaeead1bd4784dfce7066a9011aa
Sotti 2015年

Answers:


99

我有同样的问题已经有10天了,但是几分钟前我得到了解决方案!这是解决方案。我制作了一个自定义MapView并像这样覆盖onTouchEvent()。

@Override
public boolean onTouchEvent(MotionEvent ev) {
    int action = ev.getAction();
    switch (action) {
    case MotionEvent.ACTION_DOWN:
        // Disallow ScrollView to intercept touch events.
        this.getParent().requestDisallowInterceptTouchEvent(true);
        break;

    case MotionEvent.ACTION_UP:
        // Allow ScrollView to intercept touch events.
        this.getParent().requestDisallowInterceptTouchEvent(false);
        break;
    }

    // Handle MapView's touch events.
    super.onTouchEvent(ev);
    return true;
}

2
@Luizje:闪烁是由您用于每个视图的背景色引起的。因此,请确保使用corect bg颜色具有最外面的视图。
aimango 2012年

37
如果对您不起作用,请尝试改写dispatchTouchEvent方法(相同的实现,只需在最后更改超级调用)。谢谢。
Rotem 2013年

2
@Rotem您的解决方案为我工作。我在ScrollView中有一个com.google.android.gms.maps.MapView,它不适用于上面的代码。我扩展了该类,并重写了dispatchTouchEvent方法来编写您的解决方案。
Tooroop

2
@Rotem:它与dispatchTouchEvent一起使用。谢谢伙伴。Njoyee编码。
MS。

3
@Rotem,您的评论挽救了我的屁股。多谢,伙计。
昂比耶2014年

47

一种更好/更简单的方法,无需操作单独的触摸事件。如果您使用的是MapView,这将起作用:

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

全班:

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

如果使用的是MapFragment,则可以将片段放入“自定义视图”中,然后dispatchTouchEvent()进行requestDisallowInterceptTouchEvent调用。


2
谢谢老板。非常适合我。
Shohel Rana '18

1
这是最好的答案,谢谢。
Chathura Wijesinghe

不错,尽管requestDisallowInterceptTouchEvent仅必要MotionEvent.ACTION_DOWN
arekolek

21

制作自己的地图并使用。它完全适合我。

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

在您的布局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"
                />

15

对于那些想要完整的工作代码的人。这里是

自定义地图视图类

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

活动布局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>

在您的活动或片段中实例化自定义地图类

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

就这样享受


2
其他解决方案对我不起作用,这个解决方案对我有用!非常感谢!
Ruben2112

9

您可以像这样创建自定义MapView:

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

拯救了我的一天。同样适用于osmdroid mapview。大。
yubaraj poudel

8

我尝试覆盖MapView.onTouchEvent(...),但对我而言不起作用。这是运行良好的代码(覆盖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);
        }
}

由于我有很多嵌套的视图组,因此该解决方案对我来说效果很好。
Roisgoen 2015年

压倒性onInterceptTouchEvent()也对我有用,而onTouchEvent()没有。但是我虽然不需要mViewParent,但似乎可以requestDisallowInterceptTouchEvent()在视图层次结构中传播。
Klemens Zleptnig '17

2

您可以简单地将MapView放在Layout中,并覆盖onTouch或设置Click-Listener-对我来说是最简单的方法,因为我需要在ScrollView中触摸整个MapView。


1

如果滚动视图中有mapview,则必须在MapView中明确提及以下参数:

mMapView.setClickable(true);
mMapView.setFocusable(true);
mMapView.setDuplicateParentStateEnabled(false);

但是,当您指定它之后,地图视图将变得不可滚动

1

如果有人想在科特林上这堂课。
我曾经dispatchTouchEvent像@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)
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.