My application is using a lot of webviews which are lying in fragments which are hold by a ViewPager.
Whenever i swipe through the app on my Galaxy Nexus with Jelly
Even I have WebView inside a ViewPager, and fixed this problem by overriding onTouchEvent()
by extending webview class.
Here is my code:
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
requestFocusFromTouch();
}
return super.onTouchEvent(event);
}
Cheers !!!
The issue occurs because in some scenarios WebView fails to notice that its visible rect has changed, so as far as webkit is concerned the page is still not visible. Thus all touches fall outside of the window, and get rejected.
The cleanest fix is when you know the visibility of your WebView has changed (such as in response to a setPrimaryItem callback from a viewpager), call webview.onScrollChanged(webview.getScrollX(), webview.getScrollY());
You will need to subclass the webview to promote the protected onScrollChanged to a public method.
Another solution:
You don't need to extend the WebView class to fix that.. I've got that fixed by adding the following two lines right after loading the web view content (myWebView.loadUrl("..."):
wv.loadUrl("your url here");
//Add the following two lines
myWebView.scrollTo(myWebView.getScrollX(), myWebView.getScrollY()+1);
myWebView.scrollTo(myWebView.getScrollX(), myWebView.getScrollY()-1);
Hope this will help (I tested myself and it worked).
Cheers
I faced exactly the same problem. In my app wherever i had click events coded using 'touchend' in jquery bind(), this error was coming up and it used to never respond to clicks (taps).. and gave a frozen kind of feel. So I just tried replacing 'touchend' with 'click' in bind(), and it worked! responded to clicks (Taps) and also didn't show that log entry of webcoreglue..
I also found this piece of code in Android's webview code..
HTMLElement* WebViewCore::retrieveElement(int x, int y,
const QualifiedName& tagName)
{
HitTestResult hitTestResult = m_mainFrame->eventHandler()
->hitTestResultAtPoint(IntPoint(x, y), false, false,
DontHitTestScrollbars, HitTestRequest::Active | HitTestRequest::ReadOnly,
IntSize(1, 1));
if (!hitTestResult.innerNode() || !hitTestResult.innerNode()->inDocument()) {
LOGE("Should not happen: no in document Node found");
return 0;
}
const ListHashSet<RefPtr<Node> >& list = hitTestResult.rectBasedTestResult();
if (list.isEmpty()) {
LOGE("Should not happen: no rect-based-test nodes found");
return 0;
}
Node* node = hitTestResult.innerNode();
Node* element = node;
while (element && (!element->isElementNode()
|| !element->hasTagName(tagName))) {
element = element->parentNode();
}
DBG_NAV_LOGD("node=%p element=%p x=%d y=%d nodeName=%s tagName=%s", node,
element, x, y, node->nodeName().utf8().data(),
element ? ((Element*) element)->tagName().utf8().data() : "<none>");
return static_cast<WebCore::HTMLElement*>(element);
}
and this too..
// get the highlight rectangles for the touch point (x, y) with the slop
Vector<IntRect> WebViewCore::getTouchHighlightRects(int x, int y, int slop)
{
Vector<IntRect> rects;
m_mousePos = IntPoint(x - m_scrollOffsetX, y - m_scrollOffsetY);
HitTestResult hitTestResult = m_mainFrame->eventHandler()->hitTestResultAtPoint(IntPoint(x, y),
false, false, DontHitTestScrollbars, HitTestRequest::Active | HitTestRequest::ReadOnly, IntSize(slop, slop));
if (!hitTestResult.innerNode() || !hitTestResult.innerNode()->inDocument()) {
LOGE("Should not happen: no in document Node found");
return rects;
}
const ListHashSet<RefPtr<Node> >& list = hitTestResult.rectBasedTestResult();
if (list.isEmpty()) {
LOGE("Should not happen: no rect-based-test nodes found");
return rects;
}
//Rest of the part is omitted here...
Notice that log message there? I am guessing this code is for identifying the x and y axis vectors generated on clicks or taps or swipes..
It also happened to me when I was working in Cordova + Sencha Touch environment. Because
CordovaActivity
does not have anything like onScrollChanged()
method I could not apply any of the above solutions.
After hours of banging my head against the wall I discovered that some parts of web interface had been called before this was completely rendered. In my case those methods were triggered by activate
event in Ext.PanelView
. I replaced that event with painted
and since then everything works like a charm.
Although it is not copy-paste solution I hope it may help someone to save time on investigation.
Don't have a clue why it worked. I added onTouchEvent listener into my MainActivity.java to fix this issue.
public class MainActivity extends ActionBarActivity implements ActionBar.TabListener {
public class MyWebView extends WebView {
public MyWebView(Context context) {
super(context);
}
public MyWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
onScrollChanged(getScrollX(), getScrollY(), getScrollX(), getScrollY());
return super.onTouchEvent(event);
}
}