Android Google 地图 |两指滚动
Android Google Map | Two finger scrolling
我正在使用 Google 地图,
我的情况是,我在 ScrollView 中有一个地图片段,如果用户,我只需要用 双指 滚动地图只触摸一根手指地图应该不起作用,正常的滚动视图应该可以。
这是我到目前为止尝试过的 -
transparent_image.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_DOWN:
showMessage("Double finger ACTION_POINTER_DOWN");
googleMap.getUiSettings().setScrollGesturesEnabled(false);
scroll_view.requestDisallowInterceptTouchEvent(true);
return true;
case MotionEvent.ACTION_POINTER_UP:
showMessage("Double finger ACTION_POINTER_UP");
googleMap.getUiSettings().setScrollGesturesEnabled(true);
scroll_view.requestDisallowInterceptTouchEvent(false);
return true;
default:
return true;
}
}
});
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng,
gestureHandling: 'cooperative'
});
有关详细信息,请检查此
https://maps-apis.googleblog.com/2016/11/smart-scrolling-comes-to-mobile-web-maps.html
您可以在以下情况下实现本机 Android 应用程序的行为:
1) 当用户将两根手指放在 MapFragment
上时禁用 ScrollView
滚动并启用 GoogleMap
滚动;
2) 在其他情况下启用 ScrollView
滚动并禁用 GoogleMap
滚动。
对于disabling/enabling ScrollView
按条件滚动,您需要扩展ScrollView
并将onTouchEvent()
方法重写为return false
时匹配某些条件,例如 this answer of Josep Earl:
public class LockableScrollView extends ScrollView {
private boolean mScrollable = true;
public LockableScrollView(Context context) {
super(context);
}
public LockableScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LockableScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setScrollingEnabled(boolean enabled) {
mScrollable = enabled;
}
public boolean isScrollable() {
return mScrollable;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// if we can scroll pass the event to the superclass
if (mScrollable) return super.onTouchEvent(ev);
// only continue to handle the touch event if scrolling enabled
return mScrollable; // mScrollable is always false at this point
default:
return super.onTouchEvent(ev);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Don't do anything with intercepted touch events if
// we are not scrollable
if (!mScrollable) return false;
else return super.onInterceptTouchEvent(ev);
}
}
Enable/disable GoogleMap
处的滚动手势,您可以轻松调用 GoogleMap.getUiSettings()
对象上的 setAllGesturesEnabled()
和 setScrollGesturesEnabled()
并确定两根手指在 [= 上的触摸17=] 您可以使用基于 this answer 社区维基的方法:
public class TouchableWrapper extends FrameLayout {
private LockableScrollView mLockableScroll;
private GoogleMap mGoogleMap;
public TouchableWrapper(Context context) {
super(context);
}
public void setGoogleMapAndScroll(GoogleMap googleMap, LockableScrollView lockableScroll) {
mGoogleMap = googleMap;
mLockableScroll = lockableScroll;
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mGoogleMap.getUiSettings().setScrollGesturesEnabled(false);
// UPDATE: add below line to disable zoom gesture
mGoogleMap.getUiSettings().setZoomGesturesEnabled(false);
mLockableScroll.setScrollingEnabled(true);
break;
case MotionEvent.ACTION_POINTER_DOWN:
mLockableScroll.setScrollingEnabled(false);
mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
// UPDATE: add below line to enable zoom gesture
mGoogleMap.getUiSettings().setZoomGesturesEnabled(true);
break;
case MotionEvent.ACTION_POINTER_UP:
// UPDATE: add below line to disable zoom gesture
mGoogleMap.getUiSettings().setZoomGesturesEnabled(false);
mGoogleMap.getUiSettings().setScrollGesturesEnabled(false);
mLockableScroll.setScrollingEnabled(true);
break;
case MotionEvent.ACTION_UP:
// UPDATE: add below line to disable zoom gesture
mGoogleMap.getUiSettings().setZoomGesturesEnabled(false);
mGoogleMap.getUiSettings().setScrollGesturesEnabled(false);
mLockableScroll.setScrollingEnabled(true);
break;
}
return super.dispatchTouchEvent(event);
}
}
MapFragment
在这种情况下可以是这样的:
public class MultiTouchMapFragment extends MapFragment {
public View mOriginalContentView;
public TouchableWrapper mTouchView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
mOriginalContentView = super.onCreateView(inflater, parent, savedInstanceState);
mTouchView = new TouchableWrapper(getActivity());
mTouchView.addView(mOriginalContentView);
return mTouchView;
}
@Override
public View getView() {
return mOriginalContentView;
}
}
和MainActivity
这样(不需要在地图上添加标记-它只是为了测试):
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
private LockableScrollView mLockableScrollView;
private MultiTouchMapFragment mapFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLockableScrollView = (LockableScrollView) findViewById(R.id.lockable_scroll);
mapFragment = (MultiTouchMapFragment) getFragmentManager()
.findFragmentById(R.id.map_fragment);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
LatLng marker = new LatLng(48, 38);
googleMap.addMarker(new MarkerOptions().position(marker).title("Scroll"));
googleMap.getUiSettings().setAllGesturesEnabled(false);
mapFragment.mTouchView.setGoogleMapAndScroll(googleMap, mLockableScrollView);
}
}
,最后,activity_main.xml
for MainActivity
,例如,可以这样:
<[your_package_name].LockableScrollView
android:id="@+id/lockable_scroll"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="@mipmap/ic_launcher"/>
<fragment
android:id="@+id/map_fragment"
android:name="[your_package_name].MultiTouchMapFragment"
android:layout_width="match_parent"
android:layout_height="300dp"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="@mipmap/ic_launcher"/>
</LinearLayout>
</[your_package_name].LockableScrollView>
就是这样。
我正在使用 Google 地图,
我的情况是,我在 ScrollView 中有一个地图片段,如果用户,我只需要用 双指 滚动地图只触摸一根手指地图应该不起作用,正常的滚动视图应该可以。
这是我到目前为止尝试过的 -
transparent_image.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_DOWN:
showMessage("Double finger ACTION_POINTER_DOWN");
googleMap.getUiSettings().setScrollGesturesEnabled(false);
scroll_view.requestDisallowInterceptTouchEvent(true);
return true;
case MotionEvent.ACTION_POINTER_UP:
showMessage("Double finger ACTION_POINTER_UP");
googleMap.getUiSettings().setScrollGesturesEnabled(true);
scroll_view.requestDisallowInterceptTouchEvent(false);
return true;
default:
return true;
}
}
});
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng,
gestureHandling: 'cooperative'
});
有关详细信息,请检查此 https://maps-apis.googleblog.com/2016/11/smart-scrolling-comes-to-mobile-web-maps.html
您可以在以下情况下实现本机 Android 应用程序的行为:
1) 当用户将两根手指放在 MapFragment
上时禁用 ScrollView
滚动并启用 GoogleMap
滚动;
2) 在其他情况下启用 ScrollView
滚动并禁用 GoogleMap
滚动。
对于disabling/enabling ScrollView
按条件滚动,您需要扩展ScrollView
并将onTouchEvent()
方法重写为return false
时匹配某些条件,例如 this answer of Josep Earl:
public class LockableScrollView extends ScrollView {
private boolean mScrollable = true;
public LockableScrollView(Context context) {
super(context);
}
public LockableScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LockableScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setScrollingEnabled(boolean enabled) {
mScrollable = enabled;
}
public boolean isScrollable() {
return mScrollable;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// if we can scroll pass the event to the superclass
if (mScrollable) return super.onTouchEvent(ev);
// only continue to handle the touch event if scrolling enabled
return mScrollable; // mScrollable is always false at this point
default:
return super.onTouchEvent(ev);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Don't do anything with intercepted touch events if
// we are not scrollable
if (!mScrollable) return false;
else return super.onInterceptTouchEvent(ev);
}
}
Enable/disable GoogleMap
处的滚动手势,您可以轻松调用 GoogleMap.getUiSettings()
对象上的 setAllGesturesEnabled()
和 setScrollGesturesEnabled()
并确定两根手指在 [= 上的触摸17=] 您可以使用基于 this answer 社区维基的方法:
public class TouchableWrapper extends FrameLayout {
private LockableScrollView mLockableScroll;
private GoogleMap mGoogleMap;
public TouchableWrapper(Context context) {
super(context);
}
public void setGoogleMapAndScroll(GoogleMap googleMap, LockableScrollView lockableScroll) {
mGoogleMap = googleMap;
mLockableScroll = lockableScroll;
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mGoogleMap.getUiSettings().setScrollGesturesEnabled(false);
// UPDATE: add below line to disable zoom gesture
mGoogleMap.getUiSettings().setZoomGesturesEnabled(false);
mLockableScroll.setScrollingEnabled(true);
break;
case MotionEvent.ACTION_POINTER_DOWN:
mLockableScroll.setScrollingEnabled(false);
mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
// UPDATE: add below line to enable zoom gesture
mGoogleMap.getUiSettings().setZoomGesturesEnabled(true);
break;
case MotionEvent.ACTION_POINTER_UP:
// UPDATE: add below line to disable zoom gesture
mGoogleMap.getUiSettings().setZoomGesturesEnabled(false);
mGoogleMap.getUiSettings().setScrollGesturesEnabled(false);
mLockableScroll.setScrollingEnabled(true);
break;
case MotionEvent.ACTION_UP:
// UPDATE: add below line to disable zoom gesture
mGoogleMap.getUiSettings().setZoomGesturesEnabled(false);
mGoogleMap.getUiSettings().setScrollGesturesEnabled(false);
mLockableScroll.setScrollingEnabled(true);
break;
}
return super.dispatchTouchEvent(event);
}
}
MapFragment
在这种情况下可以是这样的:
public class MultiTouchMapFragment extends MapFragment {
public View mOriginalContentView;
public TouchableWrapper mTouchView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
mOriginalContentView = super.onCreateView(inflater, parent, savedInstanceState);
mTouchView = new TouchableWrapper(getActivity());
mTouchView.addView(mOriginalContentView);
return mTouchView;
}
@Override
public View getView() {
return mOriginalContentView;
}
}
和MainActivity
这样(不需要在地图上添加标记-它只是为了测试):
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
private LockableScrollView mLockableScrollView;
private MultiTouchMapFragment mapFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLockableScrollView = (LockableScrollView) findViewById(R.id.lockable_scroll);
mapFragment = (MultiTouchMapFragment) getFragmentManager()
.findFragmentById(R.id.map_fragment);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
LatLng marker = new LatLng(48, 38);
googleMap.addMarker(new MarkerOptions().position(marker).title("Scroll"));
googleMap.getUiSettings().setAllGesturesEnabled(false);
mapFragment.mTouchView.setGoogleMapAndScroll(googleMap, mLockableScrollView);
}
}
,最后,activity_main.xml
for MainActivity
,例如,可以这样:
<[your_package_name].LockableScrollView
android:id="@+id/lockable_scroll"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="@mipmap/ic_launcher"/>
<fragment
android:id="@+id/map_fragment"
android:name="[your_package_name].MultiTouchMapFragment"
android:layout_width="match_parent"
android:layout_height="300dp"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="@mipmap/ic_launcher"/>
</LinearLayout>
</[your_package_name].LockableScrollView>
就是这样。