wake-up-neo.net

MapView in einem ScrollView?

Ich hätte gerne ein MapView in einem ScrollView, aber wenn ich versuche, die Karte zu scrollen, hat das ScrollView Priorität! Gibt es eine Möglichkeit, der MapView-Priorität beim Scrollen innerhalb der Karte und ansonsten der ScrollView-Priorität zu geben?

Vielen Dank!

56
Cesar

Ich hatte ein ähnliches Problem für 10 Tage, aber ich habe vor einigen Minuten eine Lösung erhalten !! Hier ist die Lösung ... Ich habe eine benutzerdefinierte MapView erstellt und onTouchEvent () so überschrieben.

@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;
}
89
Emily Sooryum

Eine bessere/einfachere Möglichkeit, dies zu tun, ohne einzelne Berührungsereignisse zu bearbeiten. Dies funktioniert, wenn Sie MapView verwenden:

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

Volle klasse:

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

Wenn Sie MapFragment verwenden, können Sie das Fragment in eine benutzerdefinierte Ansicht einfügen und in der Funktion dispatchTouchEvent() den Aufruf requestDisallowInterceptTouchEvent ausführen.

26
AmeyaB

Erstellen Sie Ihre eigene Karte und verwenden Sie sie. Es funktioniert voll bei mir.

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 Ihrer 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"
                />
19
Zin Win Htet

Für diejenigen, die den gesamten Arbeitscode wünschen. hier ist es 

Benutzerdefinierte Kartenansichtklasse

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

Aktivitätslayout 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>

Instanziieren der benutzerdefinierten Kartenklasse in Ihrer Aktivität oder Ihrem Fragment

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

Das ist es geniessen

12
Ismail Iqbal

Sie können eine benutzerdefinierte MapView wie folgt erstellen:

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

Ich habe versucht, MapView.onTouchEvent (...) zu überschreiben, aber es funktionierte nicht für mich ... Hier ist Code, der gut funktioniert (MapView.onInterceptTouchEvent (...) überschreibt)

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

Sie können die MapView einfach in ein Layout einfügen und onTouch überschreiben oder einen Click-Listener festlegen. Dies ist für mich der einfachste Weg, da ich die gesamte MapView in meiner ScrollView berühren musste. 

2
Lukas Olsen

Wenn Sie die Kartenansicht in der Bildlaufansicht haben, müssen Sie die folgenden Parameter in der Kartenansicht explizit erwähnen:

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

Wenn jemand diese Klasse in Kotlin möchte.
Ich verwendete dispatchTouchEvent wie von @rotem vorgeschlagen

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
fupduck