Веб-просмотр Android: предотвращать перенос сенсорных жестов на родительский просмотрщик

У меня есть viewpager, который содержит много дочерних представлений; Каждый вид просмотра – это веб-просмотр. Каждый веб-просмотр имеет некоторые HTML-объекты, с которыми пользователь может взаимодействовать; Например, слайд-шоу, которое работает на жестов пальцев или перетаскиваемый круг, который пользователь может перемещать вокруг холста HTML.

Проблема заключается в том, когда пользователь выполняет жест этих объектов HTML, просмотрщик прокручивается до следующего представления. Я хочу, чтобы объекты HTML работали, когда пользователь взаимодействует с ними (viewpager не прокручивается), и просмотрщик прокручивается, когда пользователь проводит поиск в другом месте. Как я могу это сделать?

Веб-просмотр внутри Viewpager

PS Я использовал event.preventDefault() и event.stopPropagation() в JavaScript слайд-шоу HTML с надеждой, что веб-просмотр не будет передавать события касания к родительскому viewpager.

Solutions Collecting From Web of "Веб-просмотр Android: предотвращать перенос сенсорных жестов на родительский просмотрщик"

Переопределите метод "canScroll" вашего ViewPager и разрешите прокрутку только в том случае, если представление не является экземпляром WebView .

Образец:

 public class MyViewPager extends ViewPager { public MyViewPager (Context context) { super(context); } public MyViewPager (Context context, AttributeSet attrs) { super(context, attrs); } @Override protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { if(v instanceof WebView){ return true; } return super.canScroll(v, checkV, dx, x, y); } } 

Моя идея состояла в том, чтобы реализовать функцию Javascript, которая решает, какие части прокручиваются:

 function checkScroll(x, y){ var o = document.elementFromPoint(x, y); result = $('div.swiper-container').find(o).length; MyAndroidInterface.processReturnValue(result); } 

Затем переопределите эти два метода:

 @Override public boolean onInterceptTouchEvent(MotionEvent ev) { @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: homepage.callJavascript("checkScroll(" + Math.round(ev.getX()) + "," + Math.round(ev.getY()) + ")"); return super.onTouchEvent(ev); case MotionEvent.ACTION_MOVE: if (homepage.scrollSlideshowLock()) return false; 

Создайте свой собственный подкласс ViewPager и перезапишите canScroll следующим образом.

 class MyViewPager extends ViewPager { ... @Override protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { if (isInsideSlideShow(x,y)) { return true; // allow the slide show its own scrolling } else { return false; // ViewPager scrolls } } 

Вы как-то, конечно, должны знать, какая часть экрана покрыта слайд-шоу. Эти знания должны быть реализованы в методе isInsideSlideShow.

Если вы не можете получить координаты x / y слайд-шоу, другим решением может быть использование жестов, начинающихся с самой границы представления, в качестве жестов и жестов подкачки, начиная больше во внутренней области в качестве жестов слайд-шоу.

Я использую этот подход для пейджера представления, который показывает карту и график. Оба поддерживают их собственное панорамирование. Но когда пользователь начинает жест на левой или правой границе, вся карта или граф сдвигаются:

 @Override protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { int width = getWidth(); int slideWidth = Math.round(width * 0.15f); if (x < slideWidth || x > width - slideWidth) { return false; } return true; }