Android的webview:防止触摸手势传递给父视图

我有一个包含许多子视图的viewpager; 每个子视图都是一个web视图。 每个webview都有一些用户可以与之交互的HTML对象; 例如,可以在滑动手势上工作的幻灯片或用户可以在HTMLcanvas上移动的可拖动的圆圈。

问题是当用户在这些HTML对象上执行一个手势时,viewpager会滚动到下一个视图。 当用户与它们交互时,我希望HTML对象能够工作(viewpager不滚动),当用户在其他地方滑动时viewpager会滚动。 我怎样才能做到这一点?

Viewpager内部的Webviews

PS我已经在HTML幻灯片的JavaScript中使用event.preventDefault()event.stopPropagation() ,希望webview不会将触摸事件传递给父视图。

Solutions Collecting From Web of "Android的webview:防止触摸手势传递给父视图"

覆盖ViewPager"canScroll"方法,只有在视图不是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; 

创build您自己的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坐标,则另一种解决scheme可能是使用从视图边界开始的手势作为分页手势和手势,作为幻灯片放映手势在内部区域更多地开始。

我正在使用这种方法查看传呼机,显示地图和graphics。 两者都支持他们自己的平移。 但是,当用户在左边界或右边界开始手势时,整个地图或graphics被滑走:

 @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; }