Ich möchte eine MapView in einer ScrollView haben, aber wenn ich versuche, die Karte zu scrollen, hat die ScrollView Vorrang! Gibt es eine Möglichkeit, der MapView-Priorität beim Scrollen innerhalb der Karte und der ScrollView eine andere Priorität zuzuweisen?
Vielen Dank!
android
google-maps
android-maps
Cesar
quelle
quelle
Antworten:
Ich habe seit 10 Tagen das gleiche Problem, aber vor ein paar Minuten habe ich eine Lösung gefunden !! Hier ist die Lösung. Ich habe eine benutzerdefinierte MapView erstellt und onTouchEvent () wie folgt ü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; }
quelle
Eine bessere / einfachere Möglichkeit, dies zu tun, ohne einzelne Berührungsereignisse zu manipulieren. 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 ein MapFragment verwenden, können Sie das Fragment in eine benutzerdefinierte Ansicht einfügen und
dispatchTouchEvent()
denrequestDisallowInterceptTouchEvent
Anruf tätigen .quelle
requestDisallowInterceptTouchEvent
für notwendigMotionEvent.ACTION_DOWN
.Erstellen Sie Ihre eigene Karte und verwenden Sie sie. Es funktioniert voll für mich.
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 Ihrem 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" />
quelle
Für diejenigen, die den gesamten Arbeitscode wollen. hier ist es
Benutzerdefinierte Kartenansichtsklasse
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 zu genießen
quelle
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); } }
quelle
Ich habe versucht, MapView.onTouchEvent (...) zu überschreiben, aber es hat bei mir nicht funktioniert. Hier ist Code, der gut funktioniert (MapView.onInterceptTouchEvent (...) überschreiben):
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); } }
quelle
onInterceptTouchEvent()
hat auch bei mir funktioniert, wohingegenonTouchEvent()
es nicht funktioniert hat. Aber ich brauchte den mViewParent nicht, es scheint, dassrequestDisallowInterceptTouchEvent()
er in der Ansichtshierarchie weitergegeben wird.Sie können die MapView einfach in ein Layout selbst einfügen und onTouch überschreiben oder einen Click-Listener festlegen - der einfachste Weg für mich, da ich die gesamte MapView in meiner ScrollView berühren musste.
quelle
Wenn Sie eine 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);
quelle
Wenn jemand diese Klasse in Kotlin will.
Ich habe
dispatchTouchEvent
wie von @rotem vorgeschlagen verwendetclass 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) } }
quelle