WebView和ViewPager都是我们平时做Android开发非常常用的两个View控件。在一些阅读App和购物App中,我们可能需要在同一个页面上展示多个Tab及WebView。下面我将介绍下,我在ViewPager中使用WebView的一些心得和踩坑总结。
手势滑动
我们知道ViewPager默认支持水平方向手势的滑动翻页效果,根据产品实际的要求,我们可以选择支持手势滑动和屏蔽手势滑动。先说屏蔽的情况,
屏蔽手势滑动的话很简单,上一个StackOverFlow上现成的答案:
如果要支持手势滑动的话,主要会踩到这样一个坑: WebView内部js的水平滑动事件会被屏蔽。也就是说,这里我们遇到了WebView与ViewPager滑动冲突的处理。
首先我们从WebView本身这个View来考虑,我们来看一下WWebView的事件分发方法是否区分当前是否消耗了触摸事件呢?
不幸的是,我们发现,WebView的onTouchEvent(MotionEvent event)方法和dispatchTouchEvent(MotionEvent ev)永远是返回true的,我们可以在google官方的bug反馈平台上看到关于这一点的讨论。
The Android webview.onTouchEvent(event) always return true
官方的回复是这样的:
简单来说就是,WebView上所有的Touch事件都会DOM事件并发送到当前的页面中,但DOM事件的处理呢是异步的,这样就没有办法在同步的onTouch方法中返回事件的处理情况。
也就是说,通过传统的View的事件分发机制来处理js的滑动事件冲突呢,应该是走不通的。
那换个角度,WebView本身是否有一些方法可以获取当前WebView没有消耗的触摸事件呢?
还真让我找到一个方法,void onUnhandledInputEvent(WebView, InputEvent),不过不知道什么原因,这个API21 add的方法,API24的时候被remove了(https://developer.android.com/sdk/api_diff/24/changes/android.webkit.WebViewClient.html)
这里有个stack overflow上的提问,Check if Android WebView is consuming touch events,也基本上和我一个思路,目前也没有好的解决办法。
这么看,只能外部告知java,当前webview是否是可左右滑动的,比如说接口通知,或者js和java的bridge方法入手,这里就不多说了。放个链接,大家自行参考下。
不过我偶然发现UC浏览器居然可以处理这个问题!!开启UC浏览器的左滑右滑前进后退功能,在js处理事件的区域,左右滑的手势被屏蔽,在没有处理的区域,左右滑的手势自动启用,还请知道原理的同学不吝告知,多谢!!
WebView资源的释放
直接上代码
1 | /** |