我正在使用谷歌地图,
我的情况是我在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; } } });
解决方法
您可以在以下情况下实现本机Android应用程序的行为:
1)当用户将两根手指放在MapFragment上时,禁用ScrollView滚动并启用GoogleMap滚动;
2)启用ScrollView滚动并在其他情况下禁用GoogleMap滚动.
要按条件禁用/启用ScrollView滚动,您需要扩展ScrollView并覆盖onTouchEvent()方法,以便在匹配某些条件时返回false,例如,如this answer的this answer中所示:
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(),并根据社区维基的this answer确定MapFragment上两个手指的触摸,您可以使用方法:
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>
就是这样.