Android Google Map |两个手指滚动 [英] Android Google Map | Two finger scrolling
问题描述
我正在使用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 $ c
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
forMainActivity
,例如,可以是这样的:
< [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 enableGoogleMap
scrolling when user placed two finger onMapFragment
;2) enable
ScrollView
scrolling and disableGoogleMap
scrolling in other case.For disabling/enabling
ScrollView
scrolling by condition, you need to extendScrollView
and override theonTouchEvent()
method to returnfalse
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 callingsetAllGesturesEnabled()
andsetScrollGesturesEnabled()
onGoogleMap.getUiSettings()
object and for determining touches of two fingers onMapFragment
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
forMainActivity
, 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屋!