Я хотел бы иметь MapView внутри ScrollView, однако, когда я пытаюсь прокрутить карту, ScrollView имеет приоритет! Есть ли способ присвоить приоритет MapView при прокрутке внутри карты, а ScrollView в противном случае?
Спасибо!
Я хотел бы иметь MapView внутри ScrollView, однако, когда я пытаюсь прокрутить карту, ScrollView имеет приоритет! Есть ли способ присвоить приоритет MapView при прокрутке внутри карты, а ScrollView в противном случае?
Спасибо!
У меня была такая же проблема в течение 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 touch events.
super.onTouchEvent(ev);
return true;
}
Создайте свою собственную карту и используйте ее. Он полностью работает для меня.
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"
/>
Это учебник с лучшим решением, работает с картой Android v2..
Для тех, кто хочет весь рабочий код. здесь
Пользовательский класс просмотра карты
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);
Чтобы он наслаждался
Вы можете создать собственный 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);
}
}
Это будет работать, если вы используете 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
.
Я пытался с переопределением 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);
}
}
Вы можете просто поместить MapView в макет самостоятельно и переопределить onTouch или установить Click-Listener - самый простой способ для меня, так как мне нужно касаться всего MapView в моем ScrollView.
Если у вас есть mapview в режиме прокрутки, вы должны явно указать параметры follwing в MapView:
mMapView.setClickable(true);
mMapView.setFocusable(true);
mMapView.setDuplicateParentStateEnabled(false);