para - manual de programacion android pdf
MapView dentro de ScrollView? (10)
Este es un tutorial con una mejor solución, funciona con android map v2 ..
Me gustaría tener una vista de mapa dentro de una vista de desplazamiento, sin embargo, cuando trato de desplazarme por el mapa, ¡la vista de desplazamiento tiene prioridad! ¿Hay alguna manera de darle prioridad a MapView cuando se desplaza dentro del mapa, y ScrollView de lo contrario?
¡Gracias!
Haga su propio mapa y úselo. Funciona completamente para mí.
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);
}}
En su diseño 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"
/>
He intentado reemplazar a MapView.onTouchEvent (...), pero no funcionó. Aquí hay un código que funciona bien (anulando 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);
}
}
He tenido el mismo problema durante 10 días, ¡pero obtuve una solución hace unos minutos! Aquí está la solución. Hice una vista de mapa personalizada y anuló onTouchEvent () de esta manera.
@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;
}
Para aquellos que quieren todo el código de trabajo. aquí está
Clase de vista de mapa personalizada
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);
}
}
Diseño de la actividad 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>
Crear una instancia de la clase de mapa personalizado en su actividad o fragmento
CustomMapView mapView = (CustomMapView) findViewById(R.id.mapView);
Eso es lo que disfrutas
Puede crear una vista de mapa personalizada como esta:
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);
}
}
Si alguien quiere esta clase en kotlin.
Utilicé dispatchTouchEvent
como sugerido por @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)
}
}
Si tiene una vista de mapa en la vista de desplazamiento, debe mencionar explícitamente los siguientes parámetros a MapView:
mMapView.setClickable(true);
mMapView.setFocusable(true);
mMapView.setDuplicateParentStateEnabled(false);
Simplemente puede poner MapView en un Layout y anular onTouch o configurar un Click-Listener, la manera más fácil para mí, ya que necesitaba un toque en todo el MapView en mi ScrollView.
Una forma mejor / más simple de hacer esto sin manipular eventos táctiles individuales. Esto funcionará si está usando MapView:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
/**
* Request all parents to relinquish the touch events
*/
getParent().requestDisallowInterceptTouchEvent(true);
return super.dispatchTouchEvent(ev);
}
Clase completa:
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 está utilizando un MapFragment, puede colocar el fragmento en una vista personalizada y en el dispatchTouchEvent()
realizar la llamada requestDisallowInterceptTouchEvent
.