私のアプリケーションは、ViewPagerによって保持されているフラグメントにある多くのWebビューを使用しています。
Jellybeanを搭載したGalaxy Nexusのアプリをスワイプするたびに、次のコンソールメッセージが何度も表示されます。
08-23 13:44:03.374: E/webcoreglue(21690): Should not happen: no rect-based-test nodes found
私が問題を解決できるように、誰がここで何が間違っているのか説明できますか?
この問題は、WebViewが表示される四角形が変更されていることにWebViewが気付かないシナリオがあるため、Webkitが懸念する限り、ページがまだ表示されないために発生します。したがって、すべてのタッチはウィンドウの外に落ち、拒否されます。
最もクリーンな修正は、WebViewの可視性が変更されたことがわかっている場合(ビューページャーからのsetPrimaryItemコールバックへの応答など)、webview.onScrollChanged(webview.getScrollX(), webview.getScrollY());
を呼び出します
保護されたonScrollChangedをパブリックメソッドにプロモートするには、webviewをサブクラス化する必要があります。
私はこの正確な問題を抱えていました。問題はまさに、Rahul Doleが上記の答えで言ったことです。
私はこれに数日かけてさまざまなことを試みています。向きが変わると、目に見えるWebView onLongClickが再び機能することに気づいたので、この小さな宝石を思いつきました。確かに非常にハッキーですが、動作します!
WebViewを拡張するクラスでこれを使用:
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
int temp_ScrollY = getScrollY();
scrollTo(getScrollX(), getScrollY() + 1);
scrollTo(getScrollX(), temp_ScrollY);
}
return super.onTouchEvent(event);
}
私はまったく同じ問題に直面しました。私のアプリでは、jquery bind()で「touchend」を使用してコード化されたクリックイベントが発生していましたが、このエラーが発生し、クリック(タップ)に応答することはありませんでした。それで私はbind()で 'touchend'を 'click'に置き換えようとしましたが、うまくいきました!クリック(タップ)に応答し、webcoreglueのログエントリも表示しませんでした。
また、このコードはAndroidのwebviewコードにもあります。
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);
}
これも..
// 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...
そこにログメッセージがあることに注意してください?このコードは、クリックまたはタップまたはスワイプで生成されたxおよびy軸ベクトルを識別するためのものだと思います。
なぜ機能したのか、手がかりはありません。この問題を修正するために、onTouchEventリスナーをMainActivity.Javaに追加しました。
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);
}
}
WebViewを含むJellyBeanおよびViewPager +フラグメントでも同じ問題が発生します。そして、同じコードがAndroid 2.2で実行されているので問題ありません。したがって、これはJB WebView実装のバグだと思います。
JBでは、WebViewで最初に表示されたフラグメントのみが正しく機能し、ログに「発生しないはずです」というエラーが発生せず、getHitTestResult()呼び出しは正しい値を返します。次のページにスワイプすると、ログにエラーが表示され、getHitTestResult()はゼロとヌルのみを返します。
空のコンテナでフラグメントを作成し、WebViewを作成し、それらを設定し、ViewPagerで現在のフラグメントがアクティブになったときにのみデータをロードするソリューションを1つだけ見つけました。この場合、WebViewは必要に応じて機能します。しかし、残念ながら、これはViewPagerでページをスムーズにスワイプするという考えを完全に破ります。
明日は、ViewPagerのフラグメントを複合ビューに置き換えようとします。チャンスはほとんどありませんが、結果が成功するかどうかをお知らせします。
別の解決策:
それを修正するためにWebViewクラスを拡張する必要はありません。Webビューのコンテンツ(myWebView.loadUrl( "...")を読み込んだ直後に次の2行を追加することで修正しました。
wv.loadUrl("your url here");
//Add the following two lines
myWebView.scrollTo(myWebView.getScrollX(), myWebView.getScrollY()+1);
myWebView.scrollTo(myWebView.getScrollX(), myWebView.getScrollY()-1);
これが役立つことを願っています(私は自分でテストし、うまくいきました)。
乾杯
Cordova + Sencha Touch環境で働いていたときにも起こりました。 CordovaActivity
にはonScrollChanged()
メソッドのようなものがないため、上記のソリューションを適用できませんでした。
何時間も頭を壁にぶつけた後、これが完全にレンダリングされる前にWebインターフェースの一部が呼び出されたことを発見しました。私の場合、これらのメソッドはExt.PanelView
のactivate
イベントによってトリガーされました。そのイベントをpainted
に置き換えたので、それ以降はすべてが魅力のように機能します。
これはコピーペーストのソリューションではありませんが、誰かが調査の時間を節約するのに役立つことを願っています。