MapView dans un ScrollView?

Je voudrais avoir un MapView dans un ScrollView, mais quand j'essaie de faire défiler la carte, le ScrollView prend la priorité! Existe-t-il un moyen de donner la priorité MapView lors du défilement à l'intérieur de la carte, et le ScrollView sinon?

Merci!

51
demandé sur Cesar 2011-07-01 13:29:51

10 réponses

J'ai eu le même problème pendant 10 jours, mais j'ai eu une solution il y a quelques minutes!! Voici la solution. J'ai fait un MapView personnalisé et remplace onTouchEvent () comme ceci.

@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;
}
88
répondu Emily Sooryum 2011-07-30 14:39:13

Créez votre propre carte et utilisez-la. Cela fonctionne pleinement pour moi.

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

Dans votre mise en page 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"
                />
18
répondu Zin Win Htet 2017-01-25 03:19:12

Un moyen meilleur / plus simple de le faire sans manipuler les événements tactiles individuels. Cela fonctionnera si vous utilisez MapView:

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

Classe complète:

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

Si vous utilisez un MapFragment, vous pouvez placer le fragment dans une vue personnalisée, et dans le dispatchTouchEvent() Faire l'appel requestDisallowInterceptTouchEvent.

18
répondu AmeyaB 2018-07-21 00:32:16

Pour ceux qui veulent tout le code de travail . c'est ici

Classe de vue de carte personnalisée

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

Mise en page de l'activité 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>

Instanciation de la classe map personnalisée dans votre activité ou fragment

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

C'est tout profitez

12
répondu Ismail Iqbal 2016-06-06 13:47:38

Ceci est un TUTORIEL avec une meilleure solution, fonctionne avec Android map v2..

11
répondu Lorensius W. L. T 2014-02-10 05:15:59

Vous pouvez créer un MapView personnalisé comme ceci:

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
répondu Pedro Paulo Amorim 2015-08-03 18:10:33

J'ai essayé avec le remplacement de MapView.onTouchEvent(...), mais il ne fonctionne pas pour moi. Voici le code qui fonctionne bien (remplacement de 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);
        }
}
7
répondu ultraon 2015-06-24 15:00:36

Vous pouvez simplement mettre le MapView dans une mise en page elle-même et remplacer onTouch ou définir un click - Listener-moyen le plus simple pour moi puisque j'avais besoin d'une touche sur L'ensemble de MapView dans mon ScrollView.

2
répondu Lukas Olsen 2012-07-05 15:00:39

Si vous avez mapview dans la vue de défilement, vous devez mentionner explicitement les paramètres suivants à MapView:

mMapView.setClickable(true);
mMapView.setFocusable(true);
mMapView.setDuplicateParentStateEnabled(false);
1
répondu Jaya 2013-05-01 11:32:20

Si quelqu'un veut cette classe dans kotlin.
J'ai utilisé dispatchTouchEvent comme suggéré par @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
répondu fupduck 2018-06-15 08:32:03