Веб-просмотр Android: предотвращать перенос сенсорных жестов на родительский просмотрщик
У меня есть viewpager, который содержит много дочерних представлений; каждый вид просмотра - это веб-просмотр. Каждый веб-просмотр имеет некоторые HTML-объекты, с которыми пользователь может взаимодействовать; например, слайд-шоу, которое работает на жесты салфетки или перетаскиваемый круг, который пользователь может перемещать вокруг холста HTML.
Проблема заключается в том, что пользователь выполняет жест этих объектов HTML, свиток просматривает следующий вид. Я хочу, чтобы объекты HTML работали, когда пользователь взаимодействует с ними (просмотрщик не прокручивается), а просмотрщик просматривает, когда пользователь проводит поиск в другом месте. Как я могу это сделать?
![Webviews inside Viewpager]()
P.S. Я использовал event.preventDefault()
и event.stopPropagation()
в JavaScript слайд-шоу HTML с надеждой, что веб-просмотр не будет передавать сенсорные события родительскому viewpager.
Ответы
Ответ 1
Отмените метод "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);
}
}
Ответ 2
Моя идея состояла в том, чтобы реализовать функцию 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;
Ответ 3
Создайте свой собственный подкласс 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;
}