ScrollView 内に MapView を配置したいのですが、マップをスクロールしようとすると、ScrollView が優先されます。マップ内をスクロールするときに MapView を優先し、それ以外の場合は ScrollView を優先する方法はありますか?
ありがとう!
ScrollView 内に MapView を配置したいのですが、マップをスクロールしようとすると、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's touch events.
super.onTouchEvent(ev);
return true;
}
個々のタッチイベントを操作せずにこれを行うためのより良い/より簡単な方法。これは、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
呼び出しを行うことができます。
独自のマップを作成して使用します。それは私にとって完全に機能します。
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"
/>
作業コード全体が必要な人向け。ここにあります
カスタム マップ ビュー クラス
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 を Layout 自体に配置し、onTouch をオーバーライドするか、Click-Listener を設定するだけです。ScrollView で MapView 全体に触れる必要があったため、私にとって最も簡単な方法です。
スクロール ビューでマップビューを使用している場合は、MapView に次のパラメーターを明示的に指定する必要があります。
mMapView.setClickable(true);
mMapView.setFocusable(true);
mMapView.setDuplicateParentStateEnabled(false);
誰かが kotlin でこのクラスを必要とする場合。@rotemが提案したよう
に使用しましたdispatchTouchEvent
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)
}
}