Android谷歌地图|两个手指滚动

我正在使用谷歌地图,

我的情况是我在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 answerthis 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>

就是这样.

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...