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>

就是这样。