Подтвердить что ты не робот

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

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

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

Webviews inside Viewpager

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

4b9b3361

Ответ 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;
}