Android Google Map / прокрутка двумя пальцами
Я работаю с Google Map,
моем случае заключается в том, что у меня есть фрагмент карты внутри 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;
}
}
});
2 ответов
это поведение родного приложения Android вы можете достичь, когда:
1) отключить ScrollView
прокрутки и включить GoogleMap
прокрутки, когда пользователь поместил два пальца на MapFragment
;
2) включить ScrollView
прокрутка и отключение GoogleMap
прокрутка в другом случае.
для отключения/включения ScrollView
прокрутка по условию, вам нужно расширить ScrollView
и переопределить onTouchEvent()
метод, чтобы возвратить false
когда какое-то условие соответствует, например, как в ответ of Жозеф Граф:
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
вы можете легко называя setAllGesturesEnabled()
и setScrollGesturesEnabled()
on GoogleMap.getUiSettings()
объект и для определения прикосновений двух пальцев на MapFragment
вы можете использовать подход, основанный на ответ сообщества 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
в этом случае может быть такой:
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
на 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>
и это все.
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