Android Google Map |两个手指滚动 [英] Android Google Map | Two finger scrolling

查看:149
本文介绍了Android Google Map |两个手指滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Google Map,

我的情况是我在 ScrollView 中有一个地图片段,我需要滚动如果用户只触摸一个手指地图,则只能用两个手指映射。不应该正常工作,并且正常的滚动视图应该可以正常工作。



这是我尝试过的远 -

  transparent_image.setOnTouchListener(new View.OnTouchListener(){
$ b @覆盖
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);
返回true;
case MotionEvent.ACTION_POINTER_UP:
showMessage(Double finger ACTION_POINTER_UP);

googleMap.getUiSettings()。setScrollGesturesEnabled(true);

scroll_view.requestDisallowInterceptTouchEvent(false);

返回true;

默认值:
返回true;
}
}
});


解决方案

您可以在以下情况下实现原生Android应用程序的行为:
$ b <1>禁用 ScrollView 滚动并启用 GoogleMap 滚动当用户在两个手指上放置 MapFragment ;
$ b <2>启用 ScrollView 滚动并禁用 GoogleMap 在其他情况下滚动。



禁用/启用 ScrollView 按条件滚动,您需要扩展 ScrollView 并覆盖 onTouchEvent()方法当某些条件匹配时返回 false ,例如,如此答案 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);

$ b $ 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(mScrollable)return super.onTouchEvent(ev);
//只在滚动启用的情况下继续处理触摸事件
返回mScrollable; //此时mScrollable始终为false
default:
return super.onTouchEvent(ev);



@Override
public boolean onInterceptTouchEvent(MotionEvent ev){
//如果$ b不执行截获的触摸事件$ b //我们不可滚动
if(!mScrollable)return false;
else返回super.onInterceptTouchEvent(ev);






$ p $ GoogleMap
您可以轻松地在<$ c上调用 setAllGesturesEnabled() setScrollGesturesEnabled() $ c> GoogleMap.getUiSettings()对象,并用于确定 MapFragment 上两个手指的接触,您可以使用基于这个社区wiki的答案

  public类TouchableWrapper扩展FrameLayout {

私有LockableScrollView mLockableScroll;
私人GoogleMap mGoogleMap;

public TouchableWrapper(Context context){
super(context);
}

public void setGoogleMapAndScroll(GoogleMap googleMap,LockableScrollView lockableScroll){
mGoogleMap = googleMap;
mLockableScroll = lockableScroll;


$ b @Override
public boolean dispatchTouchEvent(MotionEvent event){

switch(event.getAction()& MotionEvent) ACTION_MASK){

case MotionEvent.ACTION_DOWN:
mGoogleMap.getUiSettings()。setScrollGesturesEnabled(false);
//更新:添加以下行以禁用缩放手势
mGoogleMap.getUiSettings()。setZoomGesturesEnabled(false);
mLockableScroll.setScrollingEnabled(true);
休息;

case MotionEvent.ACTION_POINTER_DOWN:
mLockableScroll.setScrollingEnabled(false);
mGoogleMap.getUiSettings()。setScrollGesturesEnabled(true);
//更新:添加以下行以启用缩放手势
mGoogleMap.getUiSettings()。setZoomGesturesEnabled(true);

break;

case MotionEvent.ACTION_POINTER_UP:
//更新:在下面添加行以禁用缩放手势
mGoogleMap.getUiSettings()。setZoomGesturesEnabled(false);
mGoogleMap.getUiSettings()。setScrollGesturesEnabled(false);
mLockableScroll.setScrollingEnabled(true);
休息;

case MotionEvent.ACTION_UP:
//更新:添加以下行以禁用缩放手势
mGoogleMap.getUiSettings()。setZoomGesturesEnabled(false);
mGoogleMap.getUiSettings()。setScrollGesturesEnabled(false);
mLockableScroll.setScrollingEnabled(true);
休息;
}
返回super.dispatchTouchEvent(event);


code
$ b $ p $ 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);
返回mTouchView;
}

@Override
public View getView(){
return mOriginalContentView;


MainActivity >那样(没有必要在地图上添加标记 - 它仅仅用于测试):

  public class MainActivity扩展AppCompatActivity实现OnMapReadyCallback {
private LockableScrollView mLockableScrollView;
私人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>





就是这样。


I am working with Google Map,

My case is that I have a map fragment inside the ScrollView and I need to scroll the map only with two finger if user touches only one finger map should not work and normal Scroll View should work.

This is what i tried so far -

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;
                    }
                }
            });

解决方案

That behavior of native Android application you can achieve when:

1) disable ScrollView scrolling and enable GoogleMap scrolling when user placed two finger on MapFragment;

2) enable ScrollView scrolling and disable GoogleMap scrolling in other case.

For disabling/enabling ScrollView scrolling by condition, you need to extend ScrollView and override the onTouchEvent() method to return false when some condition is matched, for example, as in 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 scroll gestures at GoogleMap you can easily calling setAllGesturesEnabled() and setScrollGesturesEnabled() on GoogleMap.getUiSettings() object and for determining touches of two fingers on MapFragment you can use approach, based on this answer of community wiki:

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 in this case can be like that:

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;
    }
}

and MainActivity like that (there is no need to add marker on map - it's just for test):

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);
    }
}

and, finally, activity_main.xml for MainActivity, for example, can be like this:

<[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>

and that's it.

这篇关于Android Google Map |两个手指滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆