您可以在以下情况下实现原生 Android 应用程序的行为:
1) 当用户将两根手指放在MapFragment 上时,禁用ScrollView 滚动并启用GoogleMap 滚动;
2) 在其他情况下启用ScrollView 滚动并禁用GoogleMap 滚动。
要禁用/启用ScrollView按条件滚动,您需要扩展ScrollView并覆盖onTouchEvent()方法以在某些条件匹配时返回false,例如this answer中的@987654322 @:
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);
}
}
在GoogleMap 启用/禁用滚动手势,您可以轻松地在GoogleMap.getUiSettings() 对象上调用setAllGesturesEnabled() 和setScrollGesturesEnabled(),并确定两个手指在MapFragment 上的触摸,您可以使用基于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);
}
}
最后,例如MainActivity 的activity_main.xml 可以是这样的:
<[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>
就是这样。